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"
962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/assembler-inl.h"
10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/ast/context-slot-cache.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/once.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/utils/random-number-generator.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bootstrapper.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compilation-cache.h"
17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/conversions.h"
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h"
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h"
2162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/feedback-vector.h"
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h"
2313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/heap/array-buffer-tracker-inl.h"
24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/heap/code-stats.h"
2562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/heap/embedder-tracing.h"
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/gc-idle-time-handler.h"
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/gc-tracer.h"
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/incremental-marking.h"
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/mark-compact-inl.h"
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/mark-compact.h"
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/memory-reducer.h"
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/object-stats.h"
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/objects-visiting-inl.h"
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/objects-visiting.h"
35109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/heap/remembered-set.h"
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/scavenge-job.h"
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/scavenger-inl.h"
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/store-buffer.h"
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/interpreter/interpreter.h"
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/regexp/jsregexp.h"
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/runtime-profiler.h"
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/snapshot/natives.h"
433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#include "src/snapshot/serializer-common.h"
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/snapshot/snapshot.h"
45109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/tracing/trace-event.h"
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h"
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/v8.h"
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8threads.h"
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/vm-state-inl.h"
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct Heap::StrongRootsList {
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object** start;
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object** end;
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* next;
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
61109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass IdleScavengeObserver : public AllocationObserver {
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IdleScavengeObserver(Heap& heap, intptr_t step_size)
64109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : AllocationObserver(step_size), heap_(heap) {}
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Step(int bytes_allocated, Address, size_t) override {
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    heap_.ScheduleIdleScavengeIfNeeded(bytes_allocated);
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Heap& heap_;
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::Heap()
7513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    : external_memory_(0),
76f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      external_memory_limit_(kExternalAllocationSoftLimit),
7713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      external_memory_at_last_mark_compact_(0),
78bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate_(nullptr),
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code_range_size_(0),
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // semispace_size_ should be a power of 2 and old_generation_size_ should
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // be a multiple of Page::kPageSize.
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_semi_space_size_(8 * (kPointerSize / 4) * MB),
83f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      initial_semispace_size_(MB),
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_old_generation_size_(700ul * (kPointerSize / 4) * MB),
8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      initial_max_old_generation_size_(max_old_generation_size_),
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      initial_old_generation_size_(max_old_generation_size_ /
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   kInitalOldGenerationLimitFactor),
88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      old_generation_size_configured_(false),
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_executable_size_(256ul * (kPointerSize / 4) * MB),
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Variables set based on semispace_size_ and old_generation_size_ in
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // ConfigureHeap.
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Will be 4 * reserved_semispace_size_ to ensure that young
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // generation can be aligned to its size.
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      maximum_committed_(0),
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      survived_since_last_expansion_(0),
96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      survived_last_scavenge_(0),
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      always_allocate_scope_count_(0),
983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      memory_pressure_level_(MemoryPressureLevel::kNone),
9962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      out_of_memory_callback_(nullptr),
10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      out_of_memory_callback_data_(nullptr),
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      contexts_disposed_(0),
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      number_of_disposed_maps_(0),
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      global_ic_age_(0),
104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      new_space_(nullptr),
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      old_space_(NULL),
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code_space_(NULL),
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      map_space_(NULL),
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      lo_space_(NULL),
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_state_(NOT_IN_GC),
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_post_processing_depth_(0),
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      allocations_count_(0),
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      raw_allocations_hash_(0),
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ms_count_(0),
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_count_(0),
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      remembered_unmapped_pages_index_(0),
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      allocation_timeout_(0),
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      old_generation_allocation_limit_(initial_old_generation_size_),
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      inline_allocation_disabled_(false),
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer_(nullptr),
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      promoted_objects_size_(0),
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      promotion_ratio_(0),
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      semi_space_copied_object_size_(0),
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      previous_semi_space_copied_object_size_(0),
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      semi_space_copied_rate_(0),
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      nodes_died_in_new_space_(0),
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      nodes_copied_in_new_space_(0),
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      nodes_promoted_(0),
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      maximum_size_scavenges_(0),
131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_idle_notification_time_(0.0),
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_gc_time_(0.0),
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scavenge_collector_(nullptr),
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      mark_compact_collector_(nullptr),
135bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      memory_allocator_(nullptr),
136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      store_buffer_(nullptr),
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      incremental_marking_(nullptr),
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      gc_idle_time_handler_(nullptr),
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      memory_reducer_(nullptr),
140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      live_object_stats_(nullptr),
141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      dead_object_stats_(nullptr),
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scavenge_job_(nullptr),
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      idle_scavenge_observer_(nullptr),
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new_space_allocation_counter_(0),
145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      old_generation_allocation_counter_at_last_gc_(0),
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      old_generation_size_at_last_gc_(0),
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gcs_since_last_deopt_(0),
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      global_pretenuring_feedback_(nullptr),
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ring_buffer_full_(false),
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ring_buffer_end_(0),
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      promotion_queue_(this),
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      configured_(false),
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_gc_flags_(Heap::kNoGCFlags),
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_gc_callback_flags_(GCCallbackFlags::kNoGCCallbackFlags),
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      external_string_table_(this),
156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      gc_callbacks_depth_(0),
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      deserialization_complete_(false),
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      strong_roots_list_(NULL),
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      heap_iterator_depth_(0),
16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      local_embedder_heap_tracer_(nullptr),
16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      fast_promotion_mode_(false),
162c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      force_oom_(false),
16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      delay_sweeper_tasks_for_testing_(false),
16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      pending_layout_change_object_(nullptr) {
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Allow build-time customization of the max semispace size. Building
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// V8 with snapshots and a non-default max semispace size is much
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// easier if you can define it as part of the build environment.
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(V8_MAX_SEMISPACE_SIZE)
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Ensure old_generation_size_ is a multiple of kPageSize.
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((max_old_generation_size_ & (Page::kPageSize - 1)) == 0);
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_native_contexts_list(NULL);
177c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_allocation_sites_list(Smi::kZero);
178c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_encountered_weak_collections(Smi::kZero);
179c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_encountered_weak_cells(Smi::kZero);
180c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_encountered_transition_arrays(Smi::kZero);
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Put a dummy entry in the remembered pages so we can find the list the
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // minidump even if there are no real unmapped pages.
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RememberUnmappedPage(NULL, false);
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
186c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochsize_t Heap::Capacity() {
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return new_space_->Capacity() + OldGenerationCapacity();
190bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
191bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
192c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochsize_t Heap::OldGenerationCapacity() {
193bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (!HasBeenSetUp()) return 0;
194bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
195bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return old_space_->Capacity() + code_space_->Capacity() +
196bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         map_space_->Capacity() + lo_space_->SizeOfObjects();
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochsize_t Heap::CommittedOldGenerationMemory() {
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!HasBeenSetUp()) return 0;
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return old_space_->CommittedMemory() + code_space_->CommittedMemory() +
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         map_space_->CommittedMemory() + lo_space_->Size();
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
206f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochsize_t Heap::CommittedMemory() {
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
209f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return new_space_->CommittedMemory() + CommittedOldGenerationMemory();
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t Heap::CommittedPhysicalMemory() {
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return new_space_->CommittedPhysicalMemory() +
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         old_space_->CommittedPhysicalMemory() +
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         code_space_->CommittedPhysicalMemory() +
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         map_space_->CommittedPhysicalMemory() +
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         lo_space_->CommittedPhysicalMemory();
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
223f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochsize_t Heap::CommittedMemoryExecutable() {
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
226f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return static_cast<size_t>(memory_allocator()->SizeExecutable());
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateMaximumCommitted() {
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return;
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
233f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const size_t current_committed_memory = CommittedMemory();
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (current_committed_memory > maximum_committed_) {
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maximum_committed_ = current_committed_memory;
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
239c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochsize_t Heap::Available() {
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
242c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t total = 0;
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllSpaces spaces(this);
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    total += space->Available();
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return total;
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::HasBeenSetUp() {
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return old_space_ != NULL && code_space_ != NULL && map_space_ != NULL &&
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         lo_space_ != NULL;
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochGarbageCollector Heap::SelectGarbageCollector(AllocationSpace space,
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              const char** reason) {
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Is global GC requested?
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (space != NEW_SPACE) {
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->gc_compactor_caused_by_request()->Increment();
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reason = "GC in old space requested";
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MARK_COMPACTOR;
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) {
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reason = "GC in old space forced by flags";
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MARK_COMPACTOR;
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
271c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (incremental_marking()->NeedsFinalization() &&
272c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      AllocationLimitOvershotByLargeMargin()) {
273c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *reason = "Incremental marking needs finalization";
274c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return MARK_COMPACTOR;
275c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
276c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Is there enough space left in OLD to guarantee that a scavenge can
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // succeed?
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Note that MemoryAllocator->MaxAvailable() undercounts the memory available
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for object promotion. It counts only the bytes that the memory
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // allocator has not yet allocated from the OS and assigned to any space,
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and does not count available bytes already in the old space or code
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // space.  Undercounting is safe---we may get an unrequested full GC when
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // a scavenge would have succeeded.
286c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (memory_allocator()->MaxAvailable() <= new_space_->Size()) {
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ->gc_compactor_caused_by_oldspace_exhaustion()
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ->Increment();
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reason = "scavenge might not succeed";
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MARK_COMPACTOR;
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Default
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *reason = NULL;
296c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return YoungGenerationCollector();
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::SetGCState(HeapState state) {
30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  gc_state_ = state;
30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(1238405): Combine the infrastructure for --heap-stats and
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --log-gc to avoid the complicated preprocessor and flag testing.
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportStatisticsBeforeGC() {
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Heap::ReportHeapStatistics will also log NewSpace statistics when
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// compiled --log-gc is set.  The following logic is used to avoid
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// double logging.
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (FLAG_heap_stats || FLAG_log_gc) new_space_->CollectStatistics();
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_heap_stats) {
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ReportHeapStatistics("Before GC");
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (FLAG_log_gc) {
314f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    new_space_->ReportStatistics();
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
316f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (FLAG_heap_stats || FLAG_log_gc) new_space_->ClearHistograms();
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_log_gc) {
319f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    new_space_->CollectStatistics();
320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    new_space_->ReportStatistics();
321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    new_space_->ClearHistograms();
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::PrintShortHeapStatistics() {
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!FLAG_trace_gc_verbose) return;
329c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  PrintIsolate(isolate_, "Memory allocator,   used: %6" PRIuS
330c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         " KB,"
331c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         " available: %6" PRIuS " KB\n",
332bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch               memory_allocator()->Size() / KB,
333bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch               memory_allocator()->Available() / KB);
334c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  PrintIsolate(isolate_, "New space,          used: %6" PRIuS
335bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
336c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", available: %6" PRIuS
337bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
338c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", committed: %6" PRIuS " KB\n",
339f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch               new_space_->Size() / KB, new_space_->Available() / KB,
340f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch               new_space_->CommittedMemory() / KB);
341c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  PrintIsolate(isolate_, "Old space,          used: %6" PRIuS
342bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
343c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", available: %6" PRIuS
344bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
345c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", committed: %6" PRIuS " KB\n",
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               old_space_->SizeOfObjects() / KB, old_space_->Available() / KB,
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               old_space_->CommittedMemory() / KB);
348c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  PrintIsolate(isolate_, "Code space,         used: %6" PRIuS
349bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
350c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", available: %6" PRIuS
351bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
352c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", committed: %6" PRIuS "KB\n",
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               code_space_->SizeOfObjects() / KB, code_space_->Available() / KB,
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               code_space_->CommittedMemory() / KB);
355c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  PrintIsolate(isolate_, "Map space,          used: %6" PRIuS
356bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
357c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", available: %6" PRIuS
358bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
359c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", committed: %6" PRIuS " KB\n",
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               map_space_->SizeOfObjects() / KB, map_space_->Available() / KB,
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               map_space_->CommittedMemory() / KB);
362c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  PrintIsolate(isolate_, "Large object space, used: %6" PRIuS
363bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", available: %6" PRIuS
365bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
366c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", committed: %6" PRIuS " KB\n",
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               lo_space_->SizeOfObjects() / KB, lo_space_->Available() / KB,
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               lo_space_->CommittedMemory() / KB);
369c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  PrintIsolate(isolate_, "All spaces,         used: %6" PRIuS
370bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
371c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", available: %6" PRIuS
372bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
373c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         ", committed: %6" PRIuS "KB\n",
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               this->SizeOfObjects() / KB, this->Available() / KB,
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               this->CommittedMemory() / KB);
376c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  PrintIsolate(isolate_, "External memory reported: %6" PRId64 " KB\n",
377c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch               external_memory_ / KB);
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintIsolate(isolate_, "Total time spent in GC  : %.1f ms\n",
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               total_gc_time_ms_);
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(1238405): Combine the infrastructure for --heap-stats and
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --log-gc to avoid the complicated preprocessor and flag testing.
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportStatisticsAfterGC() {
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Similar to the before GC, we use some complicated logic to ensure that
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NewSpace statistics are logged exactly once when --log-gc is turned on.
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(DEBUG)
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_heap_stats) {
389f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    new_space_->CollectStatistics();
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ReportHeapStatistics("After GC");
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (FLAG_log_gc) {
392f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    new_space_->ReportStatistics();
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (FLAG_log_gc) new_space_->ReportStatistics();
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount);
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       ++i) {
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int count = deferred_counters_[i];
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    deferred_counters_[i] = 0;
401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (count > 0) {
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      count--;
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->CountUsage(static_cast<v8::Isolate::UseCounterFeature>(i));
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::IncrementDeferredCount(v8::Isolate::UseCounterFeature feature) {
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  deferred_counters_[feature]++;
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool Heap::UncommitFromSpace() { return new_space_->UncommitFromSpace(); }
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::GarbageCollectionPrologue() {
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllowHeapAllocation for_the_first_part_of_prologue;
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    gc_count_++;
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_verify_heap) {
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Verify();
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Reset GC statistics.
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  promoted_objects_size_ = 0;
429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  previous_semi_space_copied_object_size_ = semi_space_copied_object_size_;
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  semi_space_copied_object_size_ = 0;
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  nodes_died_in_new_space_ = 0;
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  nodes_copied_in_new_space_ = 0;
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  nodes_promoted_ = 0;
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateMaximumCommitted();
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC);
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_gc_verbose) Print();
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ReportStatisticsBeforeGC();
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
445f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (new_space_->IsAtMaximumCapacity()) {
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maximum_size_scavenges_++;
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maximum_size_scavenges_ = 0;
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CheckNewSpaceExpansionCriteria();
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UpdateNewSpaceAllocationCounter();
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
454c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochsize_t Heap::SizeOfObjects() {
455c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t total = 0;
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllSpaces spaces(this);
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    total += space->SizeOfObjects();
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return total;
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* Heap::GetSpaceName(int idx) {
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (idx) {
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case NEW_SPACE:
467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "new_space";
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "old_space";
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MAP_SPACE:
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "map_space";
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CODE_SPACE:
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "code_space";
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case LO_SPACE:
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "large_object_space";
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RepairFreeListsAfterDeserialization() {
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PagedSpaces spaces(this);
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (PagedSpace* space = spaces.next(); space != NULL;
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       space = spaces.next()) {
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    space->RepairFreeListsAfterDeserialization();
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::MergeAllocationSitePretenuringFeedback(
49213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    const base::HashMap& local_pretenuring_feedback) {
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSite* site = nullptr;
49413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for (base::HashMap::Entry* local_entry = local_pretenuring_feedback.Start();
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       local_entry != nullptr;
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       local_entry = local_pretenuring_feedback.Next(local_entry)) {
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    site = reinterpret_cast<AllocationSite*>(local_entry->key);
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MapWord map_word = site->map_word();
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (map_word.IsForwardingAddress()) {
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      site = AllocationSite::cast(map_word.ToForwardingAddress());
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // We have not validated the allocation site yet, since we have not
504109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // dereferenced the site during collecting information.
505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // This is an inlined check of AllocationMemento::IsValid.
506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!site->IsAllocationSite() || site->IsZombie()) continue;
507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int value =
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        static_cast<int>(reinterpret_cast<intptr_t>(local_entry->value));
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_GT(value, 0);
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (site->IncrementMementoFoundCount(value)) {
513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      global_pretenuring_feedback_->LookupOrInsert(site,
514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                                   ObjectHash(site->address()));
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
51962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass Heap::SkipStoreBufferScope {
52062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public:
52162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  explicit SkipStoreBufferScope(StoreBuffer* store_buffer)
52262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      : store_buffer_(store_buffer) {
52362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    store_buffer_->MoveAllEntriesToRememberedSet();
52462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    store_buffer_->SetMode(StoreBuffer::IN_GC);
52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
52662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
52762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ~SkipStoreBufferScope() {
52862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(store_buffer_->Empty());
52962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    store_buffer_->SetMode(StoreBuffer::NOT_IN_GC);
53062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
53162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
53262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private:
53362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreBuffer* store_buffer_;
53462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch};
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Heap::PretenuringScope {
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit PretenuringScope(Heap* heap) : heap_(heap) {
539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    heap_->global_pretenuring_feedback_ =
540f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        new base::HashMap(kInitialFeedbackCapacity);
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ~PretenuringScope() {
544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete heap_->global_pretenuring_feedback_;
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    heap_->global_pretenuring_feedback_ = nullptr;
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Heap* heap_;
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessPretenuringFeedback() {
554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool trigger_deoptimization = false;
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_allocation_site_pretenuring) {
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int tenure_decisions = 0;
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int dont_tenure_decisions = 0;
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int allocation_mementos_found = 0;
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int allocation_sites = 0;
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int active_allocation_sites = 0;
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationSite* site = nullptr;
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step 1: Digest feedback for recorded allocation sites.
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool maximum_size_scavenge = MaximumSizeScavenge();
56613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    for (base::HashMap::Entry* e = global_pretenuring_feedback_->Start();
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         e != nullptr; e = global_pretenuring_feedback_->Next(e)) {
568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      allocation_sites++;
569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      site = reinterpret_cast<AllocationSite*>(e->key);
570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int found_count = site->memento_found_count();
571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // An entry in the storage does not imply that the count is > 0 because
572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // allocation sites might have been reset due to too many objects dying
573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // in old space.
574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (found_count > 0) {
575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(site->IsAllocationSite());
576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        active_allocation_sites++;
577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        allocation_mementos_found += found_count;
578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (site->DigestPretenuringFeedback(maximum_size_scavenge)) {
579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          trigger_deoptimization = true;
580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (site->GetPretenureMode() == TENURED) {
582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          tenure_decisions++;
583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        } else {
584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          dont_tenure_decisions++;
585109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step 2: Deopt maybe tenured allocation sites if necessary.
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool deopt_maybe_tenured = DeoptMaybeTenuredAllocationSites();
591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (deopt_maybe_tenured) {
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Object* list_element = allocation_sites_list();
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      while (list_element->IsAllocationSite()) {
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        site = AllocationSite::cast(list_element);
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(site->IsAllocationSite());
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        allocation_sites++;
597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (site->IsMaybeTenure()) {
598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          site->set_deopt_dependent_code(true);
599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          trigger_deoptimization = true;
600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        list_element = site->weak_next();
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (trigger_deoptimization) {
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->stack_guard()->RequestDeoptMarkedAllocationSites();
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_trace_pretenuring_statistics &&
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (allocation_mementos_found > 0 || tenure_decisions > 0 ||
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         dont_tenure_decisions > 0)) {
612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintIsolate(isolate(),
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   "pretenuring: deopt_maybe_tenured=%d visited_sites=%d "
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   "active_sites=%d "
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   "mementos=%d tenured=%d not_tenured=%d\n",
616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   deopt_maybe_tenured ? 1 : 0, allocation_sites,
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   active_allocation_sites, allocation_mementos_found,
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   tenure_decisions, dont_tenure_decisions);
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::DeoptMarkedAllocationSites() {
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(hpayer): If iterating over the allocation sites list becomes a
626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // performance issue, use a cache data structure in heap instead.
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* list_element = allocation_sites_list();
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (list_element->IsAllocationSite()) {
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationSite* site = AllocationSite::cast(list_element);
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (site->deopt_dependent_code()) {
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      site->dependent_code()->MarkCodeForDeoptimization(
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate_, DependentCode::kAllocationSiteTenuringChangedGroup);
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      site->set_deopt_dependent_code(false);
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    list_element = site->weak_next();
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Deoptimizer::DeoptimizeMarkedCode(isolate_);
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::GarbageCollectionEpilogue() {
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // In release mode, we only zap the from space under heap verification.
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (Heap::ShouldZapGarbage()) {
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ZapFromSpace();
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Verify();
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowHeapAllocation for_the_rest_of_the_epilogue;
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_print_global_handles) isolate_->global_handles()->Print();
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_print_handles) PrintHandles();
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_gc_verbose) Print();
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_code_stats) ReportCodeStatistics("After GC");
660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_check_handle_count) CheckHandleCount();
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_deopt_every_n_garbage_collections > 0) {
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(jkummerow/ulan/jarin): This is not safe! We can't assume that
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the topmost optimized frame can be deoptimized safely, because it
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // might not have a lazy bailout point right after its current PC.
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (++gcs_since_last_deopt_ == FLAG_deopt_every_n_garbage_collections) {
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Deoptimizer::DeoptimizeAll(isolate());
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gcs_since_last_deopt_ = 0;
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateMaximumCommitted();
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->alive_after_last_gc()->Set(
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(SizeOfObjects()));
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->string_table_capacity()->Set(
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      string_table()->Capacity());
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->number_of_symbols()->Set(
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      string_table()->NumberOfElements());
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (CommittedMemory() > 0) {
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->external_fragmentation_total()->AddSample(
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(100 - (SizeOfObjects() * 100.0) / CommittedMemory()));
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_fraction_new_space()->AddSample(static_cast<int>(
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (new_space()->CommittedMemory() * 100.0) / CommittedMemory()));
688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate_->counters()->heap_fraction_old_space()->AddSample(static_cast<int>(
689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (old_space()->CommittedMemory() * 100.0) / CommittedMemory()));
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_fraction_code_space()->AddSample(
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>((code_space()->CommittedMemory() * 100.0) /
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         CommittedMemory()));
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_fraction_map_space()->AddSample(static_cast<int>(
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (map_space()->CommittedMemory() * 100.0) / CommittedMemory()));
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_fraction_lo_space()->AddSample(static_cast<int>(
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (lo_space()->CommittedMemory() * 100.0) / CommittedMemory()));
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_total_committed()->AddSample(
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(CommittedMemory() / KB));
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_total_used()->AddSample(
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(SizeOfObjects() / KB));
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_map_space_committed()->AddSample(
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(map_space()->CommittedMemory() / KB));
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_code_space_committed()->AddSample(
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(code_space()->CommittedMemory() / KB));
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_maximum_committed()->AddSample(
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(MaximumCommittedMemory() / KB));
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UPDATE_COUNTERS_FOR_SPACE(space)                \
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->space##_bytes_available()->Set( \
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(space()->Available()));          \
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->space##_bytes_committed()->Set( \
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(space()->CommittedMemory()));    \
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->space##_bytes_used()->Set(      \
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(space()->SizeOfObjects()));
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UPDATE_FRAGMENTATION_FOR_SPACE(space)                          \
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (space()->CommittedMemory() > 0) {                                \
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->external_fragmentation_##space()->AddSample( \
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(100 -                                         \
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         (space()->SizeOfObjects() * 100.0) /          \
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             space()->CommittedMemory()));             \
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(space) \
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_FOR_SPACE(space)                         \
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_FRAGMENTATION_FOR_SPACE(space)
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_FOR_SPACE(new_space)
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_space)
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(code_space)
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(map_space)
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(lo_space)
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef UPDATE_COUNTERS_FOR_SPACE
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef UPDATE_FRAGMENTATION_FOR_SPACE
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ReportStatisticsAfterGC();
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Remember the last top pointer so that we can later find out
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // whether we allocated in new space since the last GC.
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_top_after_last_gc_ = new_space()->top();
745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  last_gc_time_ = MonotonicallyIncreasingTimeInMs();
746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReduceNewSpaceSize();
748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::PreprocessStackTraces() {
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WeakFixedArray::Iterator iterator(weak_stack_trace_list());
753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* elements;
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while ((elements = iterator.Next<FixedArray>())) {
755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int j = 1; j < elements->length(); j += 4) {
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Object* maybe_code = elements->get(j + 2);
757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // If GC happens while adding a stack trace to the weak fixed array,
758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // which has been copied into a larger backing store, we may run into
759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // a stack trace that has already been preprocessed. Guard against this.
760bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!maybe_code->IsAbstractCode()) break;
761bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      AbstractCode* abstract_code = AbstractCode::cast(maybe_code);
762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int offset = Smi::cast(elements->get(j + 3))->value();
763bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      int pos = abstract_code->SourcePosition(offset);
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      elements->set(j + 2, Smi::FromInt(pos));
765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We must not compact the weak fixed list here, as we may be in the middle
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // of writing to it, when the GC triggered. Instead, we reset the root value.
769c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_weak_stack_trace_list(Smi::kZero);
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass GCCallbacksScope {
774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit GCCallbacksScope(Heap* heap) : heap_(heap) {
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    heap_->gc_callbacks_depth_++;
777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ~GCCallbacksScope() { heap_->gc_callbacks_depth_--; }
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool CheckReenter() { return heap_->gc_callbacks_depth_ == 1; }
781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Heap* heap_;
784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::HandleGCRequest() {
7883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (HighMemoryPressure()) {
7893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    incremental_marking()->reset_request_type();
7903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CheckMemoryPressure();
7913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (incremental_marking()->request_type() ==
7923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             IncrementalMarking::COMPLETE_MARKING) {
7933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    incremental_marking()->reset_request_type();
794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    CollectAllGarbage(current_gc_flags_,
795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      GarbageCollectionReason::kFinalizeMarkingViaStackGuard,
796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      current_gc_callback_flags_);
7973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (incremental_marking()->request_type() ==
7983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                 IncrementalMarking::FINALIZATION &&
7993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             incremental_marking()->IsMarking() &&
800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             !incremental_marking()->finalize_marking_completed()) {
8013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    incremental_marking()->reset_request_type();
802f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    FinalizeIncrementalMarking(
803f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        GarbageCollectionReason::kFinalizeMarkingViaStackGuard);
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ScheduleIdleScavengeIfNeeded(int bytes_allocated) {
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_job_->ScheduleIdleTaskIfNeeded(this, bytes_allocated);
810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
812f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Heap::FinalizeIncrementalMarking(GarbageCollectionReason gc_reason) {
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_incremental_marking) {
814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    isolate()->PrintWithTimestamp(
815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        "[IncrementalMarking] (%s).\n",
816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Heap::GarbageCollectionReasonToString(gc_reason));
817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HistogramTimerScope incremental_marking_scope(
820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->counters()->gc_incremental_marking_finalize());
821109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE_EVENT0("v8", "V8.GCIncrementalMarkingFinalize");
822bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  TRACE_GC(tracer(), GCTracer::Scope::MC_INCREMENTAL_FINALIZE);
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GCCallbacksScope scope(this);
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (scope.CheckReenter()) {
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllowHeapAllocation allow_allocation;
8283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      TRACE_GC(tracer(), GCTracer::Scope::MC_INCREMENTAL_EXTERNAL_PROLOGUE);
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VMState<EXTERNAL> state(isolate_);
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HandleScope handle_scope(isolate_);
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CallGCPrologueCallbacks(kGCTypeIncrementalMarking, kNoGCCallbackFlags);
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incremental_marking()->FinalizeIncrementally();
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GCCallbacksScope scope(this);
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (scope.CheckReenter()) {
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllowHeapAllocation allow_allocation;
8393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      TRACE_GC(tracer(), GCTracer::Scope::MC_INCREMENTAL_EXTERNAL_EPILOGUE);
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VMState<EXTERNAL> state(isolate_);
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HandleScope handle_scope(isolate_);
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CallGCEpilogueCallbacks(kGCTypeIncrementalMarking, kNoGCCallbackFlags);
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHistogramTimer* Heap::GCTypeTimer(GarbageCollector collector) {
849c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (IsYoungGenerationCollector(collector)) {
850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return isolate_->counters()->gc_scavenger();
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!incremental_marking()->IsStopped()) {
853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (ShouldReduceMemory()) {
854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate_->counters()->gc_finalize_reduce_memory();
855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate_->counters()->gc_finalize();
857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return isolate_->counters()->gc_compactor();
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Heap::CollectAllGarbage(int flags, GarbageCollectionReason gc_reason,
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             const v8::GCCallbackFlags gc_callback_flags) {
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Since we are ignoring the return value, the exact choice of space does
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // not matter, so long as we do not specify NEW_SPACE, which would not
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // cause a full GC.
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(flags);
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CollectGarbage(OLD_SPACE, gc_reason, gc_callback_flags);
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(kNoGCFlags);
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
874f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Heap::CollectAllAvailableGarbage(GarbageCollectionReason gc_reason) {
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Since we are ignoring the return value, the exact choice of space does
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // not matter, so long as we do not specify NEW_SPACE, which would not
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // cause a full GC.
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Major GC would invoke weak handle callbacks on weakly reachable
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // handles, but won't collect weakly reachable objects until next
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // major GC.  Therefore if we collect aggressively and weak handle callback
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // has been invoked, we rerun major GC to release objects which become
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // garbage.
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Note: as weak callbacks can execute arbitrary code, we cannot
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // hope that eventually there will be no weak callbacks invocations.
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Therefore stop recollecting after several attempts.
88662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (gc_reason == GarbageCollectionReason::kLastResort) {
88762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    InvokeOutOfMemoryCallback();
88862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
88962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  RuntimeCallTimerScope(isolate(), &RuntimeCallStats::GC_AllAvailableGarbage);
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;
893c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    isolate()->optimizing_compile_dispatcher()->Flush(
894c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        OptimizingCompileDispatcher::BlockingBehavior::kDontBlock);
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate()->ClearSerializerData();
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(kMakeHeapIterableMask | kReduceMemoryFootprintMask);
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->compilation_cache()->Clear();
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kMaxNumberOfAttempts = 7;
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kMinNumberOfAttempts = 2;
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) {
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!CollectGarbage(MARK_COMPACTOR, gc_reason, NULL,
903109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                        v8::kGCCallbackFlagCollectAllAvailableGarbage) &&
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        attempt + 1 >= kMinNumberOfAttempts) {
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(kNoGCFlags);
909f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_space_->Shrink();
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UncommitFromSpace();
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
913f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Heap::ReportExternalMemoryPressure() {
914f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (external_memory_ >
915f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      (external_memory_at_last_mark_compact_ + external_memory_hard_limit())) {
916f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    CollectAllGarbage(
917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        kReduceMemoryFootprintMask | kFinalizeIncrementalMarkingMask,
918f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        GarbageCollectionReason::kExternalMemoryPressure,
919f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        static_cast<GCCallbackFlags>(kGCCallbackFlagCollectAllAvailableGarbage |
920f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     kGCCallbackFlagCollectAllExternalMemory));
921f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return;
922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incremental_marking()->IsStopped()) {
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (incremental_marking()->CanBeActivated()) {
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      StartIncrementalMarking(
926f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          i::Heap::kNoGCFlags, GarbageCollectionReason::kExternalMemoryPressure,
927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          static_cast<GCCallbackFlags>(
928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              kGCCallbackFlagSynchronousPhantomCallbackProcessing |
929f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              kGCCallbackFlagCollectAllExternalMemory));
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
931f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CollectAllGarbage(i::Heap::kNoGCFlags,
932f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        GarbageCollectionReason::kExternalMemoryPressure,
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        kGCCallbackFlagSynchronousPhantomCallbackProcessing);
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Incremental marking is turned on an has already been started.
937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    const double pressure =
938f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        static_cast<double>(external_memory_ -
939f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            external_memory_at_last_mark_compact_ -
940f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            kExternalAllocationSoftLimit) /
941f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        external_memory_hard_limit();
942f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_GE(1, pressure);
943f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    const double kMaxStepSizeOnExternalLimit = 25;
944f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    const double deadline = MonotonicallyIncreasingTimeInMs() +
945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            pressure * kMaxStepSizeOnExternalLimit;
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    incremental_marking()->AdvanceIncrementalMarking(
947f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        deadline, IncrementalMarking::GC_VIA_STACK_GUARD,
948f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        IncrementalMarking::FORCE_COMPLETION, StepOrigin::kV8);
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnsureFillerObjectAtTop() {
9543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // There may be an allocation memento behind objects in new space. Upon
9553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // evacuation of a non-full new space (or if we are on the last page) there
9563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // may be uninitialized memory behind top. We fill the remainder of the page
9573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // with a filler.
958f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Address to_top = new_space_->top();
959bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Page* page = Page::FromAddress(to_top - kPointerSize);
9603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (page->Contains(to_top)) {
9613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    int remaining_in_page = static_cast<int>(page->area_end() - to_top);
9623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CreateFillerObjectAt(to_top, remaining_in_page, ClearRecordedSlots::kNo);
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
966f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool Heap::CollectGarbage(GarbageCollector collector,
967f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          GarbageCollectionReason gc_reason,
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          const char* collector_reason,
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          const v8::GCCallbackFlags gc_callback_flags) {
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The VM is in the GC state until exiting this function.
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VMState<GC> state(isolate_);
97262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  RuntimeCallTimerScope(isolate(), &RuntimeCallStats::GC);
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Reset the allocation timeout to the GC interval, but make sure to
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // allow at least a few allocations after a collection. The reason
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for this is that we have a lot of allocation sequences and we
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // assume that a garbage collection will allow the subsequent
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // allocation attempts to go through.
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  allocation_timeout_ = Max(6, FLAG_gc_interval);
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureFillerObjectAtTop();
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
985c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (IsYoungGenerationCollector(collector) &&
986c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      !incremental_marking()->IsStopped()) {
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_trace_incremental_marking) {
988f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      isolate()->PrintWithTimestamp(
989f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          "[IncrementalMarking] Scavenge during marking.\n");
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool next_gc_likely_to_collect_more = false;
994c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t committed_memory_before = 0;
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (collector == MARK_COMPACTOR) {
997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    committed_memory_before = CommittedOldGenerationMemory();
998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    tracer()->Start(collector, gc_reason, collector_reason);
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(AllowHeapAllocation::IsAllowed());
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DisallowHeapAllocation no_allocation_during_gc;
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GarbageCollectionPrologue();
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
1007109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HistogramTimer* gc_type_timer = GCTypeTimer(collector);
1008109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HistogramTimerScope histogram_timer_scope(gc_type_timer);
1009109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      TRACE_EVENT0("v8", gc_type_timer->name());
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_gc_likely_to_collect_more =
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          PerformGarbageCollection(collector, gc_callback_flags);
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GarbageCollectionEpilogue();
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (collector == MARK_COMPACTOR && FLAG_track_detached_contexts) {
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->CheckDetachedContextsAfterGC();
1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (collector == MARK_COMPACTOR) {
1021c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      size_t committed_memory_after = CommittedOldGenerationMemory();
1022c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      size_t used_memory_after = PromotedSpaceSizeOfObjects();
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MemoryReducer::Event event;
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      event.type = MemoryReducer::kMarkCompact;
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      event.time_ms = MonotonicallyIncreasingTimeInMs();
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Trigger one more GC if
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // - this GC decreased committed memory,
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // - there is high fragmentation,
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // - there are live detached contexts.
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      event.next_gc_likely_to_collect_more =
1031c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          (committed_memory_before > committed_memory_after + MB) ||
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          HasHighFragmentation(used_memory_after, committed_memory_after) ||
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          (detached_contexts()->length() > 0);
103462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      event.committed_memory = committed_memory_after;
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (deserialization_complete_) {
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        memory_reducer_->NotifyMarkCompact(event);
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
10383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      memory_pressure_level_.SetValue(MemoryPressureLevel::kNone);
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    tracer()->Stop(collector);
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (collector == MARK_COMPACTOR &&
1045109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      (gc_callback_flags & (kGCCallbackFlagForced |
1046109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                            kGCCallbackFlagCollectAllAvailableGarbage)) != 0) {
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->CountUsage(v8::Isolate::kForcedGC);
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Start incremental marking for the next cycle. The heap snapshot
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generator needs incremental marking to stay off after it aborted.
1052f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // We do this only for scavenger to avoid a loop where mark-compact
1053f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // causes another mark-compact.
1054c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (IsYoungGenerationCollector(collector) &&
1055c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      !ShouldAbortIncrementalMarking()) {
1056f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    StartIncrementalMarkingIfAllocationLimitIsReached(kNoGCFlags,
1057f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                      kNoGCCallbackFlags);
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return next_gc_likely_to_collect_more;
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint Heap::NotifyContextDisposed(bool dependant_context) {
1065958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!dependant_context) {
1066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    tracer()->ResetSurvivalEvents();
1067958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    old_generation_size_configured_ = false;
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MemoryReducer::Event event;
1069109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    event.type = MemoryReducer::kPossibleGarbage;
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    event.time_ms = MonotonicallyIncreasingTimeInMs();
1071109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    memory_reducer_->NotifyPossibleGarbage(event);
1072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (isolate()->concurrent_recompilation_enabled()) {
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Flush the queued recompilation tasks.
1075c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    isolate()->optimizing_compile_dispatcher()->Flush(
1076c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        OptimizingCompileDispatcher::BlockingBehavior::kDontBlock);
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AgeInlineCaches();
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  number_of_disposed_maps_ = retained_maps()->Length();
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer()->AddContextDisposalTime(MonotonicallyIncreasingTimeInMs());
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ++contexts_disposed_;
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::StartIncrementalMarking(int gc_flags,
1085f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   GarbageCollectionReason gc_reason,
1086f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   GCCallbackFlags gc_callback_flags) {
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(incremental_marking()->IsStopped());
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(gc_flags);
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  current_gc_callback_flags_ = gc_callback_flags;
1090f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  incremental_marking()->Start(gc_reason);
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1093f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Heap::StartIncrementalMarkingIfAllocationLimitIsReached(
1094f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int gc_flags, const GCCallbackFlags gc_callback_flags) {
1095f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (incremental_marking()->IsStopped()) {
1096f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    IncrementalMarkingLimit reached_limit = IncrementalMarkingLimitReached();
1097f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (reached_limit == IncrementalMarkingLimit::kSoftLimit) {
1098f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      incremental_marking()->incremental_marking_job()->ScheduleTask(this);
1099f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else if (reached_limit == IncrementalMarkingLimit::kHardLimit) {
1100f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      StartIncrementalMarking(gc_flags,
1101f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              GarbageCollectionReason::kAllocationLimit,
1102f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              gc_callback_flags);
1103f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
1104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Heap::StartIdleIncrementalMarking(GarbageCollectionReason gc_reason) {
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  gc_idle_time_handler_->ResetNoProgressCounter();
1109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  StartIncrementalMarking(kReduceMemoryFootprintMask, gc_reason,
1110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          kNoGCCallbackFlags);
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MoveElements(FixedArray* array, int dst_index, int src_index,
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        int len) {
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (len == 0) return;
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(array->map() != fixed_cow_array_map());
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** dst_objects = array->data_start() + dst_index;
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize);
1121bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(this, array, dst_index, len);
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper class for verifying the string table.
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StringTableVerifier : public ObjectVisitor {
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Visit all HeapObject pointers in [start, end).
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Object** p = start; p < end; p++) {
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if ((*p)->IsHeapObject()) {
113313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        HeapObject* object = HeapObject::cast(*p);
113413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Isolate* isolate = object->GetIsolate();
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Check that the string is actually internalized.
113613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        CHECK(object->IsTheHole(isolate) || object->IsUndefined(isolate) ||
113713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              object->IsInternalizedString());
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void VerifyStringTable(Heap* heap) {
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StringTableVerifier verifier;
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap->string_table()->IterateElements(&verifier);
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // VERIFY_HEAP
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool Heap::ReserveSpace(Reservation* reservations, List<Address>* maps) {
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool gc_performed = true;
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int counter = 0;
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kThreshold = 20;
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (gc_performed && counter++ < kThreshold) {
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    gc_performed = false;
11563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (int space = NEW_SPACE; space < SerializerDeserializer::kNumberOfSpaces;
11573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         space++) {
1158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Reservation* reservation = &reservations[space];
1159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK_LE(1, reservation->length());
1160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (reservation->at(0).size == 0) continue;
1161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      bool perform_gc = false;
1162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (space == MAP_SPACE) {
1163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // We allocate each map individually to avoid fragmentation.
1164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        maps->Clear();
1165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        DCHECK_EQ(1, reservation->length());
1166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        int num_maps = reservation->at(0).size / Map::kSize;
1167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        for (int i = 0; i < num_maps; i++) {
1168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // The deserializer will update the skip list.
1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          AllocationResult allocation = map_space()->AllocateRawUnaligned(
1170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              Map::kSize, PagedSpace::IGNORE_SKIP_LIST);
1171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          HeapObject* free_space = nullptr;
1172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (allocation.To(&free_space)) {
1173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            // Mark with a free list node, in case we have a GC before
1174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            // deserializing.
1175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Address free_space_address = free_space->address();
1176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            CreateFillerObjectAt(free_space_address, Map::kSize,
117762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 ClearRecordedSlots::kNo);
1178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            maps->Add(free_space_address);
1179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          } else {
1180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            perform_gc = true;
1181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            break;
1182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          }
1183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
1184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else if (space == LO_SPACE) {
1185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // Just check that we can allocate during deserialization.
1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK_EQ(1, reservation->length());
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        perform_gc = !CanExpandOldGeneration(reservation->at(0).size);
1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        for (auto& chunk : *reservation) {
1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          AllocationResult allocation;
1191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          int size = chunk.size;
1192c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          DCHECK_LE(static_cast<size_t>(size),
1193c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                    MemoryAllocator::PageAreaSize(
1194c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                        static_cast<AllocationSpace>(space)));
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (space == NEW_SPACE) {
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            allocation = new_space()->AllocateRawUnaligned(size);
1197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          } else {
11983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            // The deserializer will update the skip list.
11993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            allocation = paged_space(space)->AllocateRawUnaligned(
12003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                size, PagedSpace::IGNORE_SKIP_LIST);
1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          }
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          HeapObject* free_space = nullptr;
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (allocation.To(&free_space)) {
1204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            // Mark with a free list node, in case we have a GC before
1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            // deserializing.
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Address free_space_address = free_space->address();
12073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            CreateFillerObjectAt(free_space_address, size,
120862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 ClearRecordedSlots::kNo);
12093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            DCHECK(space < SerializerDeserializer::kNumberOfPreallocatedSpaces);
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            chunk.start = free_space_address;
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            chunk.end = free_space_address + size;
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          } else {
1213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            perform_gc = true;
1214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            break;
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (perform_gc) {
1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (space == NEW_SPACE) {
1220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          CollectGarbage(NEW_SPACE, GarbageCollectionReason::kDeserializer);
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (counter > 1) {
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            CollectAllGarbage(
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                kReduceMemoryFootprintMask | kAbortIncrementalMarkingMask,
1225f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                GarbageCollectionReason::kDeserializer);
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
1227f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            CollectAllGarbage(kAbortIncrementalMarkingMask,
1228f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              GarbageCollectionReason::kDeserializer);
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        gc_performed = true;
1232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;  // Abort for-loop over spaces and retry.
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return !gc_performed;
1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnsureFromSpaceIsCommitted() {
1242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (new_space_->CommitFromSpaceIfNeeded()) return;
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Committing memory to from space failed.
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Memory is exhausted and we will die.
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V8::FatalProcessOutOfMemory("Committing semi space failed.");
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ClearNormalizedMapCaches() {
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (isolate_->bootstrapper()->IsActive() &&
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !incremental_marking()->IsMarking()) {
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = native_contexts_list();
125713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (!context->IsUndefined(isolate())) {
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // GC can happen when the context is not fully initialized,
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // so the cache can be undefined.
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* cache =
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX);
126213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (!cache->IsUndefined(isolate())) {
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NormalizedMapCache::cast(cache)->Clear();
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1265bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    context = Context::cast(context)->next_context_link();
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateSurvivalStatistics(int start_new_space_size) {
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (start_new_space_size == 0) return;
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  promotion_ratio_ = (static_cast<double>(promoted_objects_size_) /
1274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                      static_cast<double>(start_new_space_size) * 100);
1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (previous_semi_space_copied_object_size_ > 0) {
1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    promotion_rate_ =
1278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        (static_cast<double>(promoted_objects_size_) /
1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         static_cast<double>(previous_semi_space_copied_object_size_) * 100);
1280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
1281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    promotion_rate_ = 0;
1282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  semi_space_copied_rate_ =
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (static_cast<double>(semi_space_copied_object_size_) /
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       static_cast<double>(start_new_space_size) * 100);
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  double survival_rate = promotion_ratio_ + semi_space_copied_rate_;
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer()->AddSurvivalRatio(survival_rate);
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::PerformGarbageCollection(
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) {
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int freed_global_handles = 0;
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1296c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!IsYoungGenerationCollector(collector)) {
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PROFILE(isolate_, CodeMovingGCEvent());
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VerifyStringTable(this);
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCType gc_type =
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge;
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCCallbacksScope scope(this);
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (scope.CheckReenter()) {
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllowHeapAllocation allow_allocation;
1313c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      TRACE_GC(tracer(), GCTracer::Scope::EXTERNAL_PROLOGUE);
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VMState<EXTERNAL> state(isolate_);
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HandleScope handle_scope(isolate_);
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags);
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureFromSpaceIsCommitted();
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1322f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int start_new_space_size = static_cast<int>(Heap::new_space()->Size());
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Heap::PretenuringScope pretenuring_scope(this);
132662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Heap::SkipStoreBufferScope skip_store_buffer_scope(store_buffer_);
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1328c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    switch (collector) {
1329c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case MARK_COMPACTOR:
1330c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        UpdateOldGenerationAllocationCounter();
1331c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // Perform mark-sweep with optional compaction.
1332c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        MarkCompact();
1333c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        old_generation_size_configured_ = true;
1334c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // This should be updated before PostGarbageCollectionProcessing, which
1335c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // can cause another GC. Take into account the objects promoted during
1336c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // GC.
1337c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        old_generation_allocation_counter_at_last_gc_ +=
1338c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            static_cast<size_t>(promoted_objects_size_);
1339c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects();
1340c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        break;
1341c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case MINOR_MARK_COMPACTOR:
1342c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        MinorMarkCompact();
1343c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        break;
1344c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case SCAVENGER:
134562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (fast_promotion_mode_ &&
134662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            CanExpandOldGeneration(new_space()->Size())) {
134762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          tracer()->NotifyYoungGenerationHandling(
134862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              YoungGenerationHandling::kFastPromotionDuringScavenge);
134962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          EvacuateYoungGeneration();
135062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        } else {
135162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          tracer()->NotifyYoungGenerationHandling(
135262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              YoungGenerationHandling::kRegularScavenge);
135362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
135462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Scavenge();
135562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
1356c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        break;
1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ProcessPretenuringFeedback();
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateSurvivalStatistics(start_new_space_size);
1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ConfigureInitialOldGenerationSize();
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
136562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!fast_promotion_mode_ || collector == MARK_COMPACTOR) {
136662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ComputeFastPromotionMode(promotion_ratio_ + semi_space_copied_rate_);
136762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
136862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->objs_since_last_young()->Set(0);
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gc_post_processing_depth_++;
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllowHeapAllocation allow_allocation;
13743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::EXTERNAL_WEAK_GLOBAL_HANDLES);
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    freed_global_handles =
1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_->global_handles()->PostGarbageCollectionProcessing(
1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            collector, gc_callback_flags);
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gc_post_processing_depth_--;
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->eternal_handles()->PostGarbageCollectionProcessing(this);
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update relocatables.
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Relocatable::PostGarbageCollectionProcessing(isolate_);
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double gc_speed = tracer()->CombinedMarkCompactSpeedInBytesPerMillisecond();
13873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  double mutator_speed =
13883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      tracer()->CurrentOldGenerationAllocationThroughputInBytesPerMillisecond();
1389c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t old_gen_size = PromotedSpaceSizeOfObjects();
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (collector == MARK_COMPACTOR) {
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register the amount of external allocated memory.
139213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    external_memory_at_last_mark_compact_ = external_memory_;
1393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    external_memory_limit_ = external_memory_ + kExternalAllocationSoftLimit;
1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed);
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (HasLowYoungGenerationAllocationRate() &&
1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             old_generation_size_configured_) {
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DampenOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed);
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCCallbacksScope scope(this);
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (scope.CheckReenter()) {
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllowHeapAllocation allow_allocation;
1404c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      TRACE_GC(tracer(), GCTracer::Scope::EXTERNAL_EPILOGUE);
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VMState<EXTERNAL> state(isolate_);
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HandleScope handle_scope(isolate_);
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CallGCEpilogueCallbacks(gc_type, gc_callback_flags);
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VerifyStringTable(this);
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return freed_global_handles > 0;
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) {
142262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  RuntimeCallTimerScope(isolate(), &RuntimeCallStats::GCPrologueCallback);
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (gc_type & gc_prologue_callbacks_[i].gc_type) {
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!gc_prologue_callbacks_[i].pass_isolate) {
1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        v8::GCCallback callback = reinterpret_cast<v8::GCCallback>(
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            gc_prologue_callbacks_[i].callback);
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        callback(gc_type, flags);
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        gc_prologue_callbacks_[i].callback(isolate, gc_type, flags);
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
14353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (FLAG_trace_object_groups && (gc_type == kGCTypeIncrementalMarking ||
14363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                   gc_type == kGCTypeMarkSweepCompact)) {
14373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    isolate_->global_handles()->PrintObjectGroups();
14383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CallGCEpilogueCallbacks(GCType gc_type,
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   GCCallbackFlags gc_callback_flags) {
144462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  RuntimeCallTimerScope(isolate(), &RuntimeCallStats::GCEpilogueCallback);
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (gc_type & gc_epilogue_callbacks_[i].gc_type) {
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!gc_epilogue_callbacks_[i].pass_isolate) {
1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        v8::GCCallback callback = reinterpret_cast<v8::GCCallback>(
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            gc_epilogue_callbacks_[i].callback);
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        callback(gc_type, gc_callback_flags);
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        gc_epilogue_callbacks_[i].callback(isolate, gc_type, gc_callback_flags);
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MarkCompact() {
1461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PauseAllocationObserversScope pause_observers(this);
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
146362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SetGCState(MARK_COMPACT);
146462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, ResourceEvent("markcompact", "begin"));
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t size_of_objects_before_gc = SizeOfObjects();
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mark_compact_collector()->Prepare();
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ms_count_++;
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MarkCompactPrologue();
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mark_compact_collector()->CollectGarbage();
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, ResourceEvent("markcompact", "end"));
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MarkCompactEpilogue();
1480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_allocation_site_pretenuring) {
1482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    EvaluateOldSpaceLocalPretenuring(size_of_objects_before_gc);
1483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1486c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid Heap::MinorMarkCompact() { UNREACHABLE(); }
1487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Heap::MarkCompactEpilogue() {
1489c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  TRACE_GC(tracer(), GCTracer::Scope::MC_EPILOGUE);
149062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SetGCState(NOT_IN_GC);
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->objs_since_last_full()->Set(0);
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  incremental_marking()->Epilogue();
1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PreprocessStackTraces();
14973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(incremental_marking()->IsStopped());
14983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1499c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  mark_compact_collector()->marking_deque()->StopUsing();
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MarkCompactPrologue() {
1504c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  TRACE_GC(tracer(), GCTracer::Scope::MC_PROLOGUE);
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->context_slot_cache()->Clear();
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->descriptor_lookup_cache()->Clear();
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RegExpResultsCache::Clear(string_split_cache());
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RegExpResultsCache::Clear(regexp_multiple_cache());
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->compilation_cache()->MarkCompactPrologue();
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompletelyClearInstanceofCache();
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FlushNumberStringCache();
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ClearNormalizedMapCaches();
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CheckNewSpaceExpansionCriteria() {
1520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_experimental_new_space_growth_heuristic) {
1521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (new_space_->TotalCapacity() < new_space_->MaximumCapacity() &&
1522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        survived_last_scavenge_ * 100 / new_space_->TotalCapacity() >= 10) {
1523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Grow the size of new space if there is room to grow, and more than 10%
1524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // have survived the last scavenge.
1525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      new_space_->Grow();
1526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      survived_since_last_expansion_ = 0;
1527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else if (new_space_->TotalCapacity() < new_space_->MaximumCapacity() &&
1529f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             survived_since_last_expansion_ > new_space_->TotalCapacity()) {
1530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Grow the size of new space if there is room to grow, and enough data
1531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // has survived scavenge since the last expansion.
1532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    new_space_->Grow();
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    survived_since_last_expansion_ = 0;
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool IsUnscavengedHeapObject(Heap* heap, Object** p) {
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return heap->InNewSpace(*p) &&
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         !HeapObject::cast(*p)->map_word().IsForwardingAddress();
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PromotionQueue::Initialize() {
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The last to-space page may be used for promotion queue. On promotion
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // conflict, we use the emergency stack.
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) ==
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         0);
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  front_ = rear_ =
15493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      reinterpret_cast<struct Entry*>(heap_->new_space()->ToSpaceEnd());
15503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  limit_ = reinterpret_cast<struct Entry*>(
1551bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Page::FromAllocationAreaAddress(reinterpret_cast<Address>(rear_))
1552bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          ->area_start());
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emergency_stack_ = NULL;
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1556f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid PromotionQueue::Destroy() {
1557f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(is_empty());
1558f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  delete emergency_stack_;
1559f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  emergency_stack_ = NULL;
1560f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PromotionQueue::RelocateQueueHead() {
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(emergency_stack_ == NULL);
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1565bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Page* p = Page::FromAllocationAreaAddress(reinterpret_cast<Address>(rear_));
15663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  struct Entry* head_start = rear_;
15673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  struct Entry* head_end =
15683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Min(front_, reinterpret_cast<struct Entry*>(p->area_end()));
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int entries_count =
15713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      static_cast<int>(head_end - head_start) / sizeof(struct Entry);
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emergency_stack_ = new List<Entry>(2 * entries_count);
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (head_start != head_end) {
15763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    struct Entry* entry = head_start++;
1577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // New space allocation in SemiSpaceCopyObject marked the region
1578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // overlapping with promotion queue as uninitialized.
15793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    MSAN_MEMORY_IS_INITIALIZED(entry, sizeof(struct Entry));
15803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    emergency_stack_->Add(*entry);
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rear_ = head_end;
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ScavengeWeakObjectRetainer : public WeakObjectRetainer {
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit ScavengeWeakObjectRetainer(Heap* heap) : heap_(heap) {}
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Object* RetainAs(Object* object) {
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!heap_->InFromSpace(object)) {
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return object;
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MapWord map_word = HeapObject::cast(object)->map_word();
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (map_word.IsForwardingAddress()) {
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return map_word.ToForwardingAddress();
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap* heap_;
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
160662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::EvacuateYoungGeneration() {
160762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_EVACUATE);
160862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(fast_promotion_mode_);
160962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(CanExpandOldGeneration(new_space()->Size()));
161062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
161162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  mark_compact_collector()->sweeper().EnsureNewSpaceCompleted();
161262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
161362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SetGCState(SCAVENGE);
161462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  LOG(isolate_, ResourceEvent("scavenge", "begin"));
161562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
161662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Move pages from new->old generation.
161762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  PageRange range(new_space()->bottom(), new_space()->top());
161862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for (auto it = range.begin(); it != range.end();) {
161962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Page* p = (*++it)->prev_page();
162062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    p->Unlink();
162162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Page::ConvertNewToOld(p);
162262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (incremental_marking()->IsMarking())
162362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      mark_compact_collector()->RecordLiveSlotsOnPage(p);
162462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
162562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
162662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Reset new space.
162762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!new_space()->Rebalance()) {
162862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    FatalProcessOutOfMemory("NewSpace::Rebalance");
162962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
163062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  new_space()->ResetAllocationInfo();
163162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  new_space()->set_age_mark(new_space()->top());
163262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
163362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Fix up special trackers.
163462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  external_string_table_.PromoteAllNewSpaceStrings();
163562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // GlobalHandles are updated in PostGarbageCollectonProcessing
163662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
163762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  IncrementYoungSurvivorsCounter(new_space()->Size());
163862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  IncrementPromotedObjectsSize(new_space()->Size());
163962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  IncrementSemiSpaceCopiedObjectSize(0);
164062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
164162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  LOG(isolate_, ResourceEvent("scavenge", "end"));
164262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SetGCState(NOT_IN_GC);
164362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::Scavenge() {
16463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_SCAVENGE);
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RelocationLock relocation_lock(this);
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // There are soft limits in the allocation code, designed to trigger a mark
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // sweep collection by failing allocations. There is no sense in trying to
1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // trigger one during scavenge: scavenges allocation should always succeed.
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AlwaysAllocateScope scope(isolate());
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Bump-pointer allocations done during scavenge are not real allocations.
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Pause the inline allocation steps.
1655109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PauseAllocationObserversScope pause_observers(this);
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
165713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  mark_compact_collector()->sweeper().EnsureNewSpaceCompleted();
165813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
165962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SetGCState(SCAVENGE);
1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Implements Cheney's copying algorithm
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, ResourceEvent("scavenge", "begin"));
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Used for updating survived_since_last_expansion_ at function end.
1665c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t survived_watermark = PromotedSpaceSizeOfObjects();
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_collector_->SelectScavengingVisitorsTable();
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Flip the semispaces.  After flipping, to space is empty, from space has
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // live objects.
1671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_space_->Flip();
1672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_space_->ResetAllocationInfo();
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We need to sweep newly copied objects which can be either in the
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to space or promoted to the old generation.  For to-space
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects, we treat the bottom of the to space as a queue.  Newly
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // copied and unswept objects lie between a 'front' mark and the
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // allocation pointer.
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Promoted objects can go into various old-generation spaces, and
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // can be allocated internally in the spaces (from the free list).
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We treat the top of the to space as a queue of addresses of
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // promoted objects.  The addresses of newly promoted and unswept
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects lie between a 'front' mark and a 'rear' mark that is
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // updated as a side effect of promoting an object.
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There is guaranteed to be enough room at the top of the to space
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for the addresses of promoted objects: every object promoted
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frees up its size in bytes from the top of the new space, and
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects are at least one pointer in size.
1691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Address new_space_front = new_space_->ToSpaceStart();
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  promotion_queue_.Initialize();
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ScavengeVisitor scavenge_visitor(this);
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1696c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  isolate()->global_handles()->IdentifyWeakUnmodifiedObjects(
1697c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      &IsUnmodifiedHeapObject);
1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
1700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Copy roots.
17013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_ROOTS);
1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE);
1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Copy objects reachable from the old generation.
17073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_OLD_TO_NEW_POINTERS);
170813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    RememberedSet<OLD_TO_NEW>::Iterate(this, [this](Address addr) {
170913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return Scavenger::CheckAndScavengeObject(this, addr);
171013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    });
171113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
171213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    RememberedSet<OLD_TO_NEW>::IterateTyped(
171313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        this, [this](SlotType type, Address host_addr, Address addr) {
171413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          return UpdateTypedSlotHelper::UpdateTypedSlot(
171513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              isolate(), type, addr, [this](Object** addr) {
171613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                // We expect that objects referenced by code are long living.
171713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                // If we do not force promotion, then we need to clear
171813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                // old_to_new slots in dead code objects after mark-compact.
171913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                return Scavenger::CheckAndScavengeObject(
172013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                    this, reinterpret_cast<Address>(addr));
172113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              });
172213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        });
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
17263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_WEAK);
1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Copy objects reachable from the encountered weak collections list.
1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    scavenge_visitor.VisitPointer(&encountered_weak_collections_);
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Copy objects reachable from the code flushing candidates list.
17333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_CODE_FLUSH_CANDIDATES);
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MarkCompactCollector* collector = mark_compact_collector();
1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (collector->is_code_flushing_enabled()) {
1736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor);
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
17413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_SEMISPACE);
1742c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending(
1746c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      &IsUnscavengedHeapObject);
1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
174862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  isolate()
174962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ->global_handles()
175062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ->IterateNewSpaceWeakUnmodifiedRoots<
175162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          GlobalHandles::HANDLE_PHANTOM_NODES_VISIT_OTHERS>(&scavenge_visitor);
1752c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UpdateNewSpaceReferencesInExternalStringTable(
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      &UpdateNewSpaceReferenceInExternalStringTableEntry);
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  promotion_queue_.Destroy();
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  incremental_marking()->UpdateMarkingDequeAfterScavenge();
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ScavengeWeakObjectRetainer weak_object_retainer(this);
1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ProcessYoungWeakReferences(&weak_object_retainer);
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(new_space_front == new_space_->top());
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set age mark.
1767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_space_->set_age_mark(new_space_->top());
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
176913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ArrayBufferTracker::FreeDeadInNewSpace(this);
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update how much has survived scavenge.
1772c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_GE(PromotedSpaceSizeOfObjects(), survived_watermark);
1773c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  IncrementYoungSurvivorsCounter(PromotedSpaceSizeOfObjects() +
1774c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                 new_space_->Size() - survived_watermark);
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
177662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Scavenger may find new wrappers by iterating objects promoted onto a black
177762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // page.
177862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  local_embedder_heap_tracer()->RegisterWrappersWithRemoteTracer();
177962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, ResourceEvent("scavenge", "end"));
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SetGCState(NOT_IN_GC);
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::ComputeFastPromotionMode(double survival_rate) {
178662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const size_t survived_in_new_space =
178762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      survived_last_scavenge_ * 100 / new_space_->Capacity();
178862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  fast_promotion_mode_ =
178962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      !FLAG_optimize_for_size && FLAG_fast_promotion_new_space &&
179062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      !ShouldReduceMemory() && new_space_->IsAtMaximumCapacity() &&
179162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      survived_in_new_space >= kMinPromotedPercentForFastPromotionMode;
179262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (FLAG_trace_gc_verbose) {
179362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    PrintIsolate(
179462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        isolate(), "Fast promotion mode: %s survival rate: %" PRIuS "%%\n",
179562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        fast_promotion_mode_ ? "true" : "false", survived_in_new_space);
179662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
179762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochString* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                Object** p) {
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapWord first_word = HeapObject::cast(*p)->map_word();
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!first_word.IsForwardingAddress()) {
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Unreachable external string can be finalized.
180562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    String* string = String::cast(*p);
180662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!string->IsExternalString()) {
180762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // Original external string has been internalized.
180862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK(string->IsThinString());
180962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return NULL;
181062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
181162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    heap->FinalizeExternalString(string);
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // String is still reachable.
181662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  String* string = String::cast(first_word.ToForwardingAddress());
181762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (string->IsThinString()) string = ThinString::cast(string)->actual();
181862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Internalization can replace external strings with non-external strings.
181962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return string->IsExternalString() ? string : nullptr;
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateNewSpaceReferencesInExternalStringTable(
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ExternalStringTableUpdaterCallback updater_func) {
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (external_string_table_.new_space_strings_.is_empty()) return;
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** start = &external_string_table_.new_space_strings_[0];
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** end = start + external_string_table_.new_space_strings_.length();
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** last = start;
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (Object** p = start; p < end; ++p) {
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    String* target = updater_func(this, p);
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (target == NULL) continue;
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(target->IsExternalString());
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (InNewSpace(target)) {
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // String is still in new space.  Update the table entry.
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *last = target;
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ++last;
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // String got promoted.  Move it to the old string list.
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      external_string_table_.AddOldString(target);
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(last <= end);
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  external_string_table_.ShrinkNewStrings(static_cast<int>(last - start));
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateReferencesInExternalStringTable(
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ExternalStringTableUpdaterCallback updater_func) {
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update old space string references.
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (external_string_table_.old_space_strings_.length() > 0) {
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** start = &external_string_table_.old_space_strings_[0];
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** end = start + external_string_table_.old_space_strings_.length();
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Object** p = start; p < end; ++p) *p = updater_func(this, p);
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateNewSpaceReferencesInExternalStringTable(updater_func);
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ProcessAllWeakReferences(WeakObjectRetainer* retainer) {
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ProcessNativeContexts(retainer);
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ProcessAllocationSites(retainer);
1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ProcessYoungWeakReferences(WeakObjectRetainer* retainer) {
1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ProcessNativeContexts(retainer);
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) {
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* head = VisitWeakList<Context>(this, native_contexts_list(), retainer);
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update the head of the list of contexts.
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_native_contexts_list(head);
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) {
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* allocation_site_obj =
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitWeakList<AllocationSite>(this, allocation_sites_list(), retainer);
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_allocation_sites_list(allocation_site_obj);
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::ProcessWeakListRoots(WeakObjectRetainer* retainer) {
18913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  set_native_contexts_list(retainer->RetainAs(native_contexts_list()));
18923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  set_allocation_sites_list(retainer->RetainAs(allocation_sites_list()));
18933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) {
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation_scope;
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* cur = allocation_sites_list();
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool marked = false;
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (cur->IsAllocationSite()) {
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationSite* casted = AllocationSite::cast(cur);
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (casted->GetPretenureMode() == flag) {
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      casted->ResetPretenureDecision();
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      casted->set_deopt_dependent_code(true);
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      marked = true;
1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RemoveAllocationSitePretenuringFeedback(casted);
1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cur = casted->weak_next();
1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (marked) isolate_->stack_guard()->RequestDeoptMarkedAllocationSites();
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EvaluateOldSpaceLocalPretenuring(
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint64_t size_of_objects_before_gc) {
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t size_of_objects_after_gc = SizeOfObjects();
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double old_generation_survival_rate =
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (static_cast<double>(size_of_objects_after_gc) * 100) /
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<double>(size_of_objects_before_gc);
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (old_generation_survival_rate < kOldSurvivalRateLowThreshold) {
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Too many objects died in the old generation, pretenuring of wrong
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // allocation sites may be the cause for that. We have to deopt all
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // dependent code registered in the allocation sites to re-evaluate
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // our pretenuring decisions.
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ResetAllAllocationSitesDependentCode(TENURED);
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_trace_pretenuring) {
1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF(
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          "Deopt all allocation sites dependent code due to low survival "
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          "rate in the old generation %f\n",
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          old_generation_survival_rate);
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // All external strings are listed in the external string table.
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class ExternalStringTableVisitorAdapter : public ObjectVisitor {
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit ExternalStringTableVisitorAdapter(
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v8::ExternalResourceVisitor* visitor)
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : visitor_(visitor) {}
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void VisitPointers(Object** start, Object** end) {
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (Object** p = start; p < end; p++) {
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK((*p)->IsExternalString());
1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        visitor_->VisitExternalString(
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Utils::ToLocal(Handle<String>(String::cast(*p))));
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::ExternalResourceVisitor* visitor_;
1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } external_string_table_visitor(visitor);
1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
195762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  external_string_table_.IterateAll(&external_string_table_visitor);
1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
1961c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         Address new_space_front) {
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {
1963f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    SemiSpace::AssertValidRange(new_space_front, new_space_->top());
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The addresses new_space_front and new_space_.top() define a
1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // queue of unprocessed copied objects.  Process them until the
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // queue is empty.
1967f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    while (new_space_front != new_space_->top()) {
1968bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!Page::IsAlignedToPageSize(new_space_front)) {
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HeapObject* object = HeapObject::FromAddress(new_space_front);
1970c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        new_space_front +=
1971c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            StaticScavengeVisitor::IterateBody(object->map(), object);
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1973bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        new_space_front = Page::FromAllocationAreaAddress(new_space_front)
1974bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              ->next_page()
1975bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              ->area_start();
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Promote and process all the to-be-promoted objects.
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      while (!promotion_queue()->is_empty()) {
1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HeapObject* target;
19833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        int32_t size;
19843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        bool was_marked_black;
19853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        promotion_queue()->remove(&target, &size, &was_marked_black);
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Promoted object might be already partially visited
1988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // during old space pointer iteration. Thus we search specifically
1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // for pointers to from semispace instead of looking for pointers
1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // to new space.
1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(!target->IsMap());
1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1993c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        IterateAndScavengePromotedObject(target, static_cast<int>(size),
1994c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                         was_marked_black);
1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Take another spin if there are now unswept objects in new space
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // (there are currently no more unswept promoted objects).
2000f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } while (new_space_front != new_space_->top());
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_space_front;
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSTATIC_ASSERT((FixedDoubleArray::kHeaderSize & kDoubleAlignmentMask) ==
2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              0);  // NOLINT
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSTATIC_ASSERT((FixedTypedArrayBase::kDataOffset & kDoubleAlignmentMask) ==
2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              0);  // NOLINT
2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef V8_HOST_ARCH_32_BIT
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSTATIC_ASSERT((HeapNumber::kValueOffset & kDoubleAlignmentMask) !=
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              0);  // NOLINT
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Heap::GetMaximumFillToAlign(AllocationAlignment alignment) {
2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (alignment) {
2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kWordAligned:
2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 0;
2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDoubleAligned:
2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDoubleUnaligned:
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kDoubleSize - kPointerSize;
2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return 0;
2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Heap::GetFillToAlign(Address address, AllocationAlignment alignment) {
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t offset = OffsetFrom(address);
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (alignment == kDoubleAligned && (offset & kDoubleAlignmentMask) != 0)
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return kPointerSize;
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (alignment == kDoubleUnaligned && (offset & kDoubleAlignmentMask) == 0)
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return kDoubleSize - kPointerSize;  // No fill if double is always aligned.
2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return 0;
2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHeapObject* Heap::PrecedeWithFiller(HeapObject* object, int filler_size) {
20413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CreateFillerObjectAt(object->address(), filler_size, ClearRecordedSlots::kNo);
2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HeapObject::FromAddress(object->address() + filler_size);
2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHeapObject* Heap::AlignWithFiller(HeapObject* object, int object_size,
2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  int allocation_size,
2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  AllocationAlignment alignment) {
2049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int filler_size = allocation_size - object_size;
2050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(filler_size > 0);
2051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pre_filler = GetFillToAlign(object->address(), alignment);
2052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pre_filler) {
2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    object = PrecedeWithFiller(object, pre_filler);
2054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    filler_size -= pre_filler;
2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (filler_size)
20573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CreateFillerObjectAt(object->address() + object_size, filler_size,
20583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                         ClearRecordedSlots::kNo);
2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return object;
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHeapObject* Heap::DoubleAlignForDeserialization(HeapObject* object, int size) {
2064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AlignWithFiller(object, size - kPointerSize, size, kDoubleAligned);
2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RegisterNewArrayBuffer(JSArrayBuffer* buffer) {
206913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ArrayBufferTracker::RegisterNew(this, buffer);
2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::UnregisterArrayBuffer(JSArrayBuffer* buffer) {
207413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ArrayBufferTracker::Unregister(this, buffer);
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Heap::ConfigureInitialOldGenerationSize() {
2078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!old_generation_size_configured_ && tracer()->SurvivalEventsRecorded()) {
2079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    old_generation_allocation_limit_ =
2080f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Max(MinimumAllocationLimitGrowingStep(),
2081c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            static_cast<size_t>(
2082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                static_cast<double>(old_generation_allocation_limit_) *
2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                (tracer()->AverageSurvivalRatio() / 100)));
2084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2085958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2086958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          int instance_size) {
2089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* result = nullptr;
2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE);
2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Map::cast cannot be used due to uninitialized map field.
2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  reinterpret_cast<Map*>(result)->set_map(
2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      reinterpret_cast<Map*>(root(kMetaMapRootIndex)));
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_instance_type(instance_type);
2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_instance_size(instance_size);
2098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Initialize to only containing tagged fields.
2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_visitor_id(
2100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      StaticVisitorBase::GetVisitorId(instance_type, instance_size, false));
2101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_unbox_double_fields) {
2102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    reinterpret_cast<Map*>(result)
2103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        ->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
2104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  reinterpret_cast<Map*>(result)->clear_unused();
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  reinterpret_cast<Map*>(result)
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ->set_inobject_properties_or_constructor_function_index(0);
2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_bit_field(0);
2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_bit_field2(0);
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
2112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   Map::OwnsDescriptors::encode(true) |
2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   Map::ConstructionCounter::encode(Map::kNoSlackTracking);
2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3);
2115c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  reinterpret_cast<Map*>(result)->set_weak_cell_cache(Smi::kZero);
2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateMap(InstanceType instance_type,
2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   int instance_size,
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   ElementsKind elements_kind) {
2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE);
2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  isolate()->counters()->maps_created()->Increment();
2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(meta_map());
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = Map::cast(result);
2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_instance_type(instance_type);
2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_prototype(null_value(), SKIP_WRITE_BARRIER);
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_constructor_or_backpointer(null_value(), SKIP_WRITE_BARRIER);
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_instance_size(instance_size);
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->clear_unused();
2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_inobject_properties_or_constructor_function_index(0);
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_dependent_code(DependentCode::cast(empty_fixed_array()),
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          SKIP_WRITE_BARRIER);
2139c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  map->set_weak_cell_cache(Smi::kZero);
2140c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  map->set_raw_transitions(Smi::kZero);
2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_unused_property_fields(0);
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_instance_descriptors(empty_descriptor_array());
2143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_unbox_double_fields) {
2144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
2145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Must be called only after |instance_type|, |instance_size| and
2147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // |layout_descriptor| are set.
2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_visitor_id(Heap::GetStaticVisitorIdForMap(map));
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_bit_field(0);
2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_bit_field2(1 << Map::kIsExtensible);
2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
2152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   Map::OwnsDescriptors::encode(true) |
2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   Map::ConstructionCounter::encode(Map::kNoSlackTracking);
2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_bit_field3(bit_field3);
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_elements_kind(elements_kind);
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_new_target_is_base(true);
2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return map;
2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFillerObject(int size, bool double_align,
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            AllocationSpace space) {
2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationAlignment align = double_align ? kDoubleAligned : kWordAligned;
2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space, align);
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(chunk->owner()->identity() == space);
2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
217462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CreateFillerObjectAt(obj->address(), size, ClearRecordedSlots::kNo);
2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj;
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Heap::StringTypeTable Heap::string_type_table[] = {
2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  { type, size, k##camel_name##MapRootIndex }             \
2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ,
2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STRING_TYPE_LIST(STRING_TYPE_ELEMENT)
2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef STRING_TYPE_ELEMENT
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Heap::ConstantStringTable Heap::constant_string_table[] = {
2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    {"", kempty_stringRootIndex},
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CONSTANT_STRING_ELEMENT(name, contents) \
2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  { contents, k##name##RootIndex }              \
2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ,
2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT)
2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef CONSTANT_STRING_ELEMENT
2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Heap::StructTable Heap::struct_table[] = {
2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define STRUCT_TABLE_ELEMENT(NAME, Name, name)        \
2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex } \
2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ,
2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STRUCT_LIST(STRUCT_TABLE_ELEMENT)
2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef STRUCT_TABLE_ELEMENT
2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2206bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochnamespace {
2207bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2208bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid FinalizePartialMap(Heap* heap, Map* map) {
2209bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_code_cache(heap->empty_fixed_array());
2210bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_dependent_code(DependentCode::cast(heap->empty_fixed_array()));
2211c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  map->set_raw_transitions(Smi::kZero);
2212bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_instance_descriptors(heap->empty_descriptor_array());
2213bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (FLAG_unbox_double_fields) {
2214bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
2215bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2216bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_prototype(heap->null_value());
2217bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_constructor_or_backpointer(heap->null_value());
2218bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
2219bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2220bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}  // namespace
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CreateInitialMaps() {
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize);
2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Map::cast cannot be used due to uninitialized map field.
2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* new_meta_map = reinterpret_cast<Map*>(obj);
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_meta_map(new_meta_map);
2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_meta_map->set_map(new_meta_map);
2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {  // Partial map allocation
2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name)                \
2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {                                                                          \
2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Map* map;                                                                \
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocatePartialMap((instance_type), (size)).To(&map)) return false; \
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_##field_name##_map(map);                                             \
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array);
2242bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    fixed_array_map()->set_elements_kind(FAST_HOLEY_ELEMENTS);
2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined);
2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null);
2245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole);
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_PARTIAL_MAP
2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the empty array.
2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateEmptyFixedArray();
2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_empty_fixed_array(FixedArray::cast(obj));
2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = Allocate(null_map(), OLD_SPACE);
2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_null_value(Oddball::cast(obj));
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Oddball::cast(obj)->set_kind(Oddball::kNull);
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = Allocate(undefined_map(), OLD_SPACE);
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_undefined_value(Oddball::cast(obj));
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Oddball::cast(obj)->set_kind(Oddball::kUndefined);
2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(undefined_value()));
2271bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  {
2272bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    AllocationResult allocation = Allocate(the_hole_map(), OLD_SPACE);
2273bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!allocation.To(&obj)) return false;
2274bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2275bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  set_the_hole_value(Oddball::cast(obj));
2276bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Oddball::cast(obj)->set_kind(Oddball::kTheHole);
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set preliminary exception sentinel value before actually initializing it.
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_exception(null_value());
2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the empty descriptor array.
2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateEmptyFixedArray();
2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_empty_descriptor_array(DescriptorArray::cast(obj));
2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fix the instance_descriptors for the existing maps.
2289bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, meta_map());
2290bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, fixed_array_map());
2291bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, undefined_map());
2292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  undefined_map()->set_is_undetectable();
2293bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, null_map());
2294bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  null_map()->set_is_undetectable();
2295bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, the_hole_map());
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {  // Map allocation
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_MAP(instance_type, size, field_name)               \
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {                                                                 \
2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Map* map;                                                       \
2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocateMap((instance_type), size).To(&map)) return false; \
2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_##field_name##_map(map);                                    \
2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \
2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name)
2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATE_PRIMITIVE_MAP(instance_type, size, field_name, \
2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               constructor_function_index)      \
2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {                                                             \
2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_MAP((instance_type), (size), field_name);          \
2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    field_name##_map()->SetConstructorFunctionIndex(            \
2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (constructor_function_index));                          \
2314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, fixed_cow_array)
2317bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    fixed_cow_array_map()->set_elements_kind(FAST_HOLEY_ELEMENTS);
2318bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK_NE(fixed_array_map(), fixed_cow_array_map());
2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info)
2321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_info)
232262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, feedback_vector)
2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           Context::NUMBER_FUNCTION_INDEX)
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 mutable_heap_number)
2327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol,
2328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           Context::SYMBOL_FUNCTION_INDEX)
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign)
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_PRIMITIVE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean,
2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           Context::BOOLEAN_FUNCTION_INDEX);
2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized);
2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker);
2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, no_interceptor_result_sentinel);
2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception);
2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception);
23383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, optimized_out);
2339bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, stale_register);
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
234162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ALLOCATE_MAP(JS_PROMISE_CAPABILITY_TYPE, JSPromiseCapability::kSize,
234262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                 js_promise_capability);
234362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (unsigned i = 0; i < arraysize(string_type_table); i++) {
2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const StringTypeTable& entry = string_type_table[i];
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      {
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        AllocationResult allocation = AllocateMap(entry.type, entry.size);
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!allocation.To(&obj)) return false;
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Map* map = Map::cast(obj);
2351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Mark cons string maps as unstable, because their objects can change
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // maps during GC.
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (StringShape(entry.type).IsCons()) map->mark_unstable();
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      roots_[entry.index] = map;
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    {  // Create a separate external one byte string map for native sources.
235913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      AllocationResult allocation =
236013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          AllocateMap(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE,
236113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                      ExternalOneByteString::kShortSize);
2362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (!allocation.To(&obj)) return false;
2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Map* map = Map::cast(obj);
2364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      set_native_source_string_map(map);
2366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_DOUBLE_ARRAY_TYPE, fixed_double_array)
2369bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    fixed_double_array_map()->set_elements_kind(FAST_HOLEY_DOUBLE_ELEMENTS);
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(BYTE_ARRAY_TYPE, byte_array)
2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_VARSIZE_MAP(BYTECODE_ARRAY_TYPE, bytecode_array)
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FREE_SPACE_TYPE, free_space)
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_FIXED_TYPED_ARRAY_MAP(Type, type, TYPE, ctype, size) \
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ALLOCATE_VARSIZE_MAP(FIXED_##TYPE##_ARRAY_TYPE, fixed_##type##_array)
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(ALLOCATE_FIXED_TYPED_ARRAY_MAP)
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_FIXED_TYPED_ARRAY_MAP
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements)
2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell)
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell)
2386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ALLOCATE_MAP(WEAK_CELL_TYPE, WeakCell::kSize, weak_cell)
238762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ALLOCATE_MAP(CELL_TYPE, Cell::kSize, no_closures_cell)
238862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ALLOCATE_MAP(CELL_TYPE, Cell::kSize, one_closure_cell)
238962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ALLOCATE_MAP(CELL_TYPE, Cell::kSize, many_closures_cell)
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler)
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler)
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_VARSIZE_MAP(TRANSITION_ARRAY_TYPE, transition_array)
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (unsigned i = 0; i < arraysize(struct_table); i++) {
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const StructTable& entry = struct_table[i];
2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Map* map;
2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!AllocateMap(entry.type, entry.size).To(&map)) return false;
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      roots_[entry.index] = map;
2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, hash_table)
2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, ordered_hash_table)
2404f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, unseeded_number_dictionary)
2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context)
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context)
2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, with_context)
24093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, debug_evaluate_context)
2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, block_context)
2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_context)
241262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, eval_context)
2413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context)
2414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context_table)
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, native_context)
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    native_context_map()->set_dictionary_map(true);
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    native_context_map()->set_visitor_id(
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        StaticVisitorBase::kVisitNativeContext);
2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kAlignedSize,
2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 shared_function_info)
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kSize, message_object)
2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, external)
2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    external_map()->set_is_extensible(false);
2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef ALLOCATE_PRIMITIVE_MAP
2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_VARSIZE_MAP
2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_MAP
2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
24323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  {
2433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AllocationResult allocation = AllocateEmptyScopeInfo();
2434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!allocation.To(&obj)) return false;
2435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  set_empty_scope_info(ScopeInfo::cast(obj));
2438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
24393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE);
24403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (!allocation.To(&obj)) return false;
24413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
24423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  set_true_value(Oddball::cast(obj));
24433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Oddball::cast(obj)->set_kind(Oddball::kTrue);
24443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
24453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  {
24463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE);
24473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (!allocation.To(&obj)) return false;
24483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
24493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  set_false_value(Oddball::cast(obj));
24503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Oddball::cast(obj)->set_kind(Oddball::kFalse);
24513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {  // Empty arrays
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ByteArray* byte_array;
2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false;
2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_empty_byte_array(byte_array);
2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {                                                                     \
2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FixedTypedArrayBase* obj;                                           \
2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array).To(&obj)) \
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;                                                     \
2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_empty_fixed_##type##_array(obj);                                \
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(ALLOCATE_EMPTY_FIXED_TYPED_ARRAY)
2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_EMPTY_FIXED_TYPED_ARRAY
2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(empty_fixed_array()));
2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
247462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochAllocationResult Heap::AllocateHeapNumber(MutableMode mode,
2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          PretenureFlag pretenure) {
2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Statically ensure that it is safe to allocate heap numbers in paged
2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // spaces.
2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = HeapNumber::kSize;
2479f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  STATIC_ASSERT(HeapNumber::kSize <= kMaxRegularHeapObjectSize);
2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space, kDoubleUnaligned);
2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = mode == MUTABLE ? mutable_heap_number_map() : heap_number_map();
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject::cast(result)->set_map_no_write_barrier(map);
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateCell(Object* value) {
2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = Cell::kSize;
2496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  STATIC_ASSERT(Cell::kSize <= kMaxRegularHeapObjectSize);
2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(cell_map());
2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Cell::cast(result)->set_value(value);
2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocatePropertyCell() {
2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = PropertyCell::kSize;
2510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  STATIC_ASSERT(PropertyCell::kSize <= kMaxRegularHeapObjectSize);
2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(global_property_cell_map());
2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PropertyCell* cell = PropertyCell::cast(result);
2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cell->set_dependent_code(DependentCode::cast(empty_fixed_array()),
2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           SKIP_WRITE_BARRIER);
2520c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  cell->set_property_details(PropertyDetails(Smi::kZero));
2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cell->set_value(the_hole_value());
2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAllocationResult Heap::AllocateWeakCell(HeapObject* value) {
2527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int size = WeakCell::kSize;
2528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  STATIC_ASSERT(WeakCell::kSize <= kMaxRegularHeapObjectSize);
2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  {
2531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
2532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!allocation.To(&result)) return allocation;
2533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  result->set_map_no_write_barrier(weak_cell_map());
2535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  WeakCell::cast(result)->initialize(value);
2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WeakCell::cast(result)->clear_next(the_hole_value());
2537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return result;
2538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocationResult Heap::AllocateTransitionArray(int capacity) {
2542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(capacity > 0);
2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* raw_array = nullptr;
2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRawFixedArray(capacity, TENURED);
2546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!allocation.To(&raw_array)) return allocation;
2547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  raw_array->set_map_no_write_barrier(transition_array_map());
2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TransitionArray* array = TransitionArray::cast(raw_array);
2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array->set_length(capacity);
2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MemsetPointer(array->data_start(), undefined_value(), capacity);
25523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Transition arrays are tenured. When black allocation is on we have to
25533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // add the transition array to the list of encountered_transition_arrays.
25543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (incremental_marking()->black_allocation()) {
25553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    array->set_next_link(encountered_transition_arrays(),
25563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                         UPDATE_WEAK_WRITE_BARRIER);
25573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    set_encountered_transition_arrays(array);
25583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
25593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    array->set_next_link(undefined_value(), SKIP_WRITE_BARRIER);
25603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return array;
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
256462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool Heap::CreateApiObjects() {
2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate());
2566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  set_message_listeners(*TemplateList::New(isolate(), 2));
256762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  HeapObject* obj = nullptr;
256862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
256962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    AllocationResult allocation = AllocateStruct(INTERCEPTOR_INFO_TYPE);
257062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!allocation.To(&obj)) return false;
257162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
257262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  InterceptorInfo* info = InterceptorInfo::cast(obj);
257362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  info->set_flags(0);
257462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_noop_interceptor_info(info);
257562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return true;
2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateJSEntryStub() {
2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSEntryStub stub(isolate(), StackFrame::ENTRY);
2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_js_entry_code(*stub.GetCode());
2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateJSConstructEntryStub() {
2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSEntryStub stub(isolate(), StackFrame::ENTRY_CONSTRUCT);
2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_js_construct_entry_code(*stub.GetCode());
2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateFixedStubs() {
2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Here we create roots for fixed stubs. They are needed at GC
2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for cooking and uncooking (check out frames.cc).
2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The eliminates the need for doing dictionary lookup in the
2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // stub cache for these stubs.
2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate());
2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create stubs that should be there, so we don't unexpectedly have to
2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // create them if we need them during the creation of another stub.
2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Stub creation mixes raw pointers and handles in an unsafe manner so
2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we cannot create stubs while we are creating stubs.
2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeStub::GenerateStubsAheadOfTime(isolate());
2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // MacroAssembler::Abort calls (usually enabled with --debug-code) depend on
2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // CEntryStub, so we need to call GenerateStubsAheadOfTime before JSEntryStub
2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // is created.
2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // gcc-4.4 has problem generating correct code of following snippet:
2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // {  JSEntryStub stub;
2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    js_entry_code_ = *stub.GetCode();
2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // }
2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // {  JSConstructEntryStub stub;
2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    js_construct_entry_code_ = *stub.GetCode();
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // }
2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // To workaround the problem, make separate functions without inlining.
2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap::CreateJSEntryStub();
2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap::CreateJSConstructEntryStub();
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateInitialObjects() {
2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate());
2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Factory* factory = isolate()->factory();
2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The -0 value must be set before NewNumber works.
2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_minus_zero_value(*factory->NewHeapNumber(-0.0, IMMUTABLE, TENURED));
2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(std::signbit(minus_zero_value()->Number()) != 0);
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_nan_value(*factory->NewHeapNumber(
2630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      std::numeric_limits<double>::quiet_NaN(), IMMUTABLE, TENURED));
263162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_hole_nan_value(
263262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      *factory->NewHeapNumberFromBits(kHoleNanInt64, IMMUTABLE, TENURED));
2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, IMMUTABLE, TENURED));
2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_minus_infinity_value(
2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewHeapNumber(-V8_INFINITY, IMMUTABLE, TENURED));
2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate initial string table.
2638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_string_table(*StringTable::New(isolate(), kInitialStringTableSize));
2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
26403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Allocate
26413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Finish initializing oddballs after creating the string table.
2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Oddball::Initialize(isolate(), factory->undefined_value(), "undefined",
2644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      factory->nan_value(), "undefined", Oddball::kUndefined);
2645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize the null_value.
2647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Oddball::Initialize(isolate(), factory->null_value(), "null",
2648c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                      handle(Smi::kZero, isolate()), "object", Oddball::kNull);
2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2650bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Initialize the_hole_value.
2651bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Oddball::Initialize(isolate(), factory->the_hole_value(), "hole",
2652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      factory->hole_nan_value(), "undefined",
2653bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                      Oddball::kTheHole);
2654bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
26553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Initialize the true_value.
26563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Oddball::Initialize(isolate(), factory->true_value(), "true",
2657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      handle(Smi::FromInt(1), isolate()), "boolean",
26583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      Oddball::kTrue);
2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
26603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Initialize the false_value.
26613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Oddball::Initialize(isolate(), factory->false_value(), "false",
2662c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                      handle(Smi::kZero, isolate()), "boolean",
26633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      Oddball::kFalse);
2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_uninitialized_value(
2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewOddball(factory->uninitialized_map(), "uninitialized",
2667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                           handle(Smi::FromInt(-1), isolate()), "undefined",
2668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                           Oddball::kUninitialized));
2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_arguments_marker(
2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewOddball(factory->arguments_marker_map(), "arguments_marker",
2672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                           handle(Smi::FromInt(-4), isolate()), "undefined",
2673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                           Oddball::kArgumentsMarker));
2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_no_interceptor_result_sentinel(*factory->NewOddball(
2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      factory->no_interceptor_result_sentinel_map(),
2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "no_interceptor_result_sentinel", handle(Smi::FromInt(-2), isolate()),
2678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      "undefined", Oddball::kOther));
2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_termination_exception(*factory->NewOddball(
2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      factory->termination_exception_map(), "termination_exception",
2682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      handle(Smi::FromInt(-3), isolate()), "undefined", Oddball::kOther));
2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_exception(*factory->NewOddball(factory->exception_map(), "exception",
2685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     handle(Smi::FromInt(-5), isolate()),
2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     "undefined", Oddball::kException));
2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  set_optimized_out(*factory->NewOddball(factory->optimized_out_map(),
2689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         "optimized_out",
2690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         handle(Smi::FromInt(-6), isolate()),
2691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         "undefined", Oddball::kOptimizedOut));
26923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2693bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  set_stale_register(
2694bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      *factory->NewOddball(factory->stale_register_map(), "stale_register",
2695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                           handle(Smi::FromInt(-7), isolate()), "undefined",
2696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                           Oddball::kStaleRegister));
2697bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (unsigned i = 0; i < arraysize(constant_string_table); i++) {
2699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<String> str =
2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        factory->InternalizeUtf8String(constant_string_table[i].contents);
2701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    roots_[constant_string_table[i].index] = *str;
2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create the code_stubs dictionary. The initial size is set to avoid
2705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // expanding the dictionary during bootstrapping.
2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_code_stubs(*UnseededNumberDictionary::New(isolate(), 128));
2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2708c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_instanceof_cache_function(Smi::kZero);
2709c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_instanceof_cache_map(Smi::kZero);
2710c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_instanceof_cache_answer(Smi::kZero);
2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  {
2713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    HandleScope scope(isolate());
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SYMBOL_INIT(name)                                              \
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {                                                                    \
2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<String> name##d = factory->NewStringFromStaticChars(#name); \
2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Symbol> symbol(isolate()->factory()->NewPrivateSymbol());   \
2718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    symbol->set_name(*name##d);                                        \
2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    roots_[k##name##RootIndex] = *symbol;                              \
2720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PRIVATE_SYMBOL_LIST(SYMBOL_INIT)
2722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef SYMBOL_INIT
2723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  {
2726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    HandleScope scope(isolate());
2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SYMBOL_INIT(name, description)                                      \
2728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<Symbol> name = factory->NewSymbol();                               \
2729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<String> name##d = factory->NewStringFromStaticChars(#description); \
2730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  name->set_name(*name##d);                                                 \
2731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  roots_[k##name##RootIndex] = *name;
2732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PUBLIC_SYMBOL_LIST(SYMBOL_INIT)
2733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef SYMBOL_INIT
2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SYMBOL_INIT(name, description)                                      \
2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Symbol> name = factory->NewSymbol();                               \
2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<String> name##d = factory->NewStringFromStaticChars(#description); \
2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  name->set_is_well_known_symbol(true);                                     \
2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  name->set_name(*name##d);                                                 \
2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  roots_[k##name##RootIndex] = *name;
2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WELL_KNOWN_SYMBOL_LIST(SYMBOL_INIT)
2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef SYMBOL_INIT
2743958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2744958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<NameDictionary> empty_properties_dictionary =
274662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      NameDictionary::NewEmpty(isolate(), TENURED);
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  empty_properties_dictionary->SetRequiresCopyOnCapacityChange();
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_empty_properties_dictionary(*empty_properties_dictionary);
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
275062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_public_symbol_table(*empty_properties_dictionary);
275162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_api_symbol_table(*empty_properties_dictionary);
275262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_api_private_symbol_table(*empty_properties_dictionary);
275362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_number_string_cache(
2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *factory->NewFixedArray(kInitialNumberStringCacheSize * 2, TENURED));
2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate cache for single character one byte strings.
2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_single_character_string_cache(
2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *factory->NewFixedArray(String::kMaxOneByteCharCode + 1, TENURED));
2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate cache for string split and regexp-multiple.
2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_string_split_cache(*factory->NewFixedArray(
2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_regexp_multiple_cache(*factory->NewFixedArray(
2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate cache for external strings pointing to native source code.
2768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_natives_source_cache(
2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *factory->NewFixedArray(Natives::GetBuiltinsCount()));
2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_experimental_natives_source_cache(
2772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewFixedArray(ExperimentalNatives::GetBuiltinsCount()));
2773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_extra_natives_source_cache(
2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewFixedArray(ExtraNatives::GetBuiltinsCount()));
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_experimental_extra_natives_source_cache(
2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewFixedArray(ExperimentalExtraNatives::GetBuiltinsCount()));
2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_undefined_cell(*factory->NewCell(factory->undefined_value()));
2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Microtask queue uses the empty fixed array as a sentinel for "empty".
2783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of queued microtasks stored in Isolate::pending_microtask_count().
2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_microtask_queue(empty_fixed_array());
2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
278713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<FixedArray> empty_sloppy_arguments_elements =
278813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        factory->NewFixedArray(2, TENURED);
278913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    empty_sloppy_arguments_elements->set_map(sloppy_arguments_elements_map());
279013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    set_empty_sloppy_arguments_elements(*empty_sloppy_arguments_elements);
279113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
279213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
279313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  {
2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<WeakCell> cell = factory->NewWeakCell(factory->undefined_value());
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_empty_weak_cell(*cell);
2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cell->clear();
2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_detached_contexts(empty_fixed_array());
2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_retained_maps(ArrayList::cast(empty_fixed_array()));
2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_weak_object_to_code_table(
2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *WeakHashTable::New(isolate(), 16, USE_DEFAULT_MINIMUM_CAPACITY,
2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          TENURED));
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  set_weak_new_space_object_to_code_list(
2807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ArrayList::cast(*(factory->NewFixedArray(16, TENURED))));
2808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  weak_new_space_object_to_code_list()->SetLength(0);
2809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
281062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_code_coverage_list(undefined_value());
281162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2812c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_script_list(Smi::kZero);
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<SeededNumberDictionary> slow_element_dictionary =
281562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      SeededNumberDictionary::NewEmpty(isolate(), TENURED);
2816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  slow_element_dictionary->set_requires_slow_elements();
2817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_empty_slow_element_dictionary(*slow_element_dictionary);
2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_materialized_objects(*factory->NewFixedArray(0, TENURED));
2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handling of script id generation is in Heap::NextScriptId().
2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId));
2823c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_next_template_serial_number(Smi::kZero);
2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate the empty script.
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Script> script = factory->NewScript(factory->empty_string());
2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  script->set_type(Script::TYPE_NATIVE);
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_empty_script(*script);
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<PropertyCell> cell = factory->NewPropertyCell();
2831c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_array_protector(*cell);
2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cell = factory->NewPropertyCell();
2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cell->set_value(the_hole_value());
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_empty_property_cell(*cell);
2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2838bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  cell = factory->NewPropertyCell();
2839c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
284062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_array_iterator_protector(*cell);
2841bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2842bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Handle<Cell> is_concat_spreadable_cell = factory->NewCell(
2843c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      handle(Smi::FromInt(Isolate::kProtectorValid), isolate()));
2844bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  set_is_concat_spreadable_protector(*is_concat_spreadable_cell);
2845bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2846bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Handle<Cell> species_cell = factory->NewCell(
2847c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      handle(Smi::FromInt(Isolate::kProtectorValid), isolate()));
2848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  set_species_protector(*species_cell);
2849109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2850f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  cell = factory->NewPropertyCell();
2851c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
2852f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  set_string_length_protector(*cell);
2853f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2854c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<Cell> fast_array_iteration_cell = factory->NewCell(
2855c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      handle(Smi::FromInt(Isolate::kProtectorValid), isolate()));
2856c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_fast_array_iteration_protector(*fast_array_iteration_cell);
285713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
285862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  cell = factory->NewPropertyCell();
285962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
286062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_array_buffer_neutering_protector(*cell);
2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2862c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_serialized_templates(empty_fixed_array());
286362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_serialized_global_proxy_sizes(empty_fixed_array());
2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2865c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_weak_stack_trace_list(Smi::kZero);
2866c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2867c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  set_noscript_shared_function_infos(Smi::kZero);
2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize context slot cache.
2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->context_slot_cache()->Clear();
2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize descriptor cache.
2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->descriptor_lookup_cache()->Clear();
2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize compilation cache.
2876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->compilation_cache()->Clear();
287762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
287862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Finish creating JSPromiseCapabilityMap
287962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
288062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // TODO(caitp): This initialization can be removed once PromiseCapability
288162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // object is no longer used by builtins implemented in javascript.
288262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Handle<Map> map = factory->js_promise_capability_map();
288362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    map->set_inobject_properties_or_constructor_function_index(3);
288462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
288562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Map::EnsureDescriptorSlack(map, 3);
288662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
288762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    PropertyAttributes attrs =
288862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
288962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    {  // promise
289062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Descriptor d = Descriptor::DataField(factory->promise_string(),
289162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           JSPromiseCapability::kPromiseIndex,
289262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           attrs, Representation::Tagged());
289362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      map->AppendDescriptor(&d);
289462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
289562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
289662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    {  // resolve
289762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Descriptor d = Descriptor::DataField(factory->resolve_string(),
289862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           JSPromiseCapability::kResolveIndex,
289962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           attrs, Representation::Tagged());
290062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      map->AppendDescriptor(&d);
290162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
290262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
290362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    {  // reject
290462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Descriptor d = Descriptor::DataField(factory->reject_string(),
290562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           JSPromiseCapability::kRejectIndex,
290662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           attrs, Representation::Tagged());
290762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      map->AppendDescriptor(&d);
290862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
290962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
291062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    map->set_is_extensible(false);
291162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    set_js_promise_capability_map(*map);
291262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (root_index) {
2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNumberStringCacheRootIndex:
2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInstanceofCacheFunctionRootIndex:
2919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInstanceofCacheMapRootIndex:
2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInstanceofCacheAnswerRootIndex:
2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCodeStubsRootIndex:
2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kEmptyScriptRootIndex:
2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kScriptListRootIndex:
2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMaterializedObjectsRootIndex:
2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMicrotaskQueueRootIndex:
2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDetachedContextsRootIndex:
2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kWeakObjectToCodeTableRootIndex:
2928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kWeakNewSpaceObjectToCodeListRootIndex:
2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kRetainedMapsRootIndex:
293062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case kCodeCoverageListRootIndex:
2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNoScriptSharedFunctionInfosRootIndex:
2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kWeakStackTraceListRootIndex:
293313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kSerializedTemplatesRootIndex:
293462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case kSerializedGlobalProxySizesRootIndex:
293562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case kPublicSymbolTableRootIndex:
293662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case kApiSymbolTableRootIndex:
293762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case kApiPrivateSymbolTableRootIndex:
2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Smi values
2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SMI_ENTRY(type, name, Name) case k##Name##RootIndex:
2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SMI_ROOT_LIST(SMI_ENTRY)
2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef SMI_ENTRY
2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // String table
2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kStringTableRootIndex:
2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
2945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
2948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::RootCanBeTreatedAsConstant(RootListIndex root_index) {
2952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return !RootCanBeWrittenAfterInitialization(root_index) &&
2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         !InNewSpace(root(root_index));
2954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
295662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool Heap::IsUnmodifiedHeapObject(Object** p) {
295762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Object* object = *p;
295862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (object->IsSmi()) return false;
295962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  HeapObject* heap_object = HeapObject::cast(object);
296062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!object->IsJSObject()) return false;
296162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  JSObject* js_object = JSObject::cast(object);
296262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!js_object->WasConstructedFromApiFunction()) return false;
296362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  JSFunction* constructor =
296462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      JSFunction::cast(js_object->map()->GetConstructor());
296562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
296662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return constructor->initial_map() == heap_object->map();
296762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
2968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Heap::FullSizeNumberStringCacheLength() {
2970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the size of the number string cache based on the max newspace size.
2971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The number string cache has a minimum size based on twice the initial cache
2972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // size to ensure that it is bigger after being made 'full size'.
2973c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t number_string_cache_size = max_semi_space_size_ / 512;
2974c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  number_string_cache_size =
2975c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Max(static_cast<size_t>(kInitialNumberStringCacheSize * 2),
2976c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          Min<size_t>(0x4000u, number_string_cache_size));
2977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There is a string and a number per entry so the length is twice the number
2978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of entries.
2979c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return static_cast<int>(number_string_cache_size * 2);
2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::FlushNumberStringCache() {
2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Flush the number to string cache.
2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int len = number_string_cache()->length();
2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < len; i++) {
2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    number_string_cache()->set_undefined(i);
2988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMap* Heap::MapForFixedTypedArray(ExternalArrayType array_type) {
2993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Map::cast(roots_[RootIndexForFixedTypedArray(array_type)]);
2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::RootListIndex Heap::RootIndexForFixedTypedArray(
2998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ExternalArrayType array_type) {
2999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (array_type) {
3000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ARRAY_TYPE_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \
3001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case kExternal##Type##Array:                                  \
3002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return kFixed##Type##ArrayMapRootIndex;
3003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(ARRAY_TYPE_TO_ROOT_INDEX)
3005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ARRAY_TYPE_TO_ROOT_INDEX
3006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
3008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kUndefinedValueRootIndex;
3010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::RootListIndex Heap::RootIndexForEmptyFixedTypedArray(
3015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ElementsKind elementsKind) {
3016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (elementsKind) {
3017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ELEMENT_KIND_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \
3018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case TYPE##_ELEMENTS:                                           \
3019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return kEmptyFixed##Type##ArrayRootIndex;
3020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(ELEMENT_KIND_TO_ROOT_INDEX)
3022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ELEMENT_KIND_TO_ROOT_INDEX
3023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
3024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kUndefinedValueRootIndex;
3026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFixedTypedArrayBase* Heap::EmptyFixedTypedArrayForMap(Map* map) {
3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return FixedTypedArrayBase::cast(
3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]);
3033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateForeign(Address address,
3037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       PretenureFlag pretenure) {
3038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Statically ensure that it is safe to allocate foreigns in paged spaces.
3039f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  STATIC_ASSERT(Foreign::kSize <= kMaxRegularHeapObjectSize);
3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE;
3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Foreign* result = nullptr;
3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation = Allocate(foreign_map(), space);
3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_foreign_address(address);
3045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateByteArray(int length, PretenureFlag pretenure) {
3050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length < 0 || length > ByteArray::kMaxLength) {
3051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
3052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = ByteArray::SizeFor(length);
3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space);
3058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(byte_array_map());
3062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ByteArray::cast(result)->set_length(length);
3063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocationResult Heap::AllocateBytecodeArray(int length,
3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             const byte* const raw_bytecodes,
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             int frame_size,
3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             int parameter_count,
3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             FixedArray* constant_pool) {
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (length < 0 || length > BytecodeArray::kMaxLength) {
3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Bytecode array is pretenured, so constant pool array should be to.
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!InNewSpace(constant_pool));
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int size = BytecodeArray::SizeFor(length);
3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!allocation.To(&result)) return allocation;
3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->set_map_no_write_barrier(bytecode_array_map());
3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArray* instance = BytecodeArray::cast(result);
3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  instance->set_length(length);
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  instance->set_frame_size(frame_size);
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  instance->set_parameter_count(parameter_count);
3090109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  instance->set_interrupt_budget(interpreter::Interpreter::InterruptBudget());
3091f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  instance->set_osr_loop_nesting_level(0);
309262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  instance->set_bytecode_age(BytecodeArray::kNoAgeBytecodeAge);
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  instance->set_constant_pool(constant_pool);
3094109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  instance->set_handler_table(empty_fixed_array());
30953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  instance->set_source_position_table(empty_byte_array());
3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CopyBytes(instance->GetFirstBytecodeAddress(), raw_bytecodes, length);
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
310162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHeapObject* Heap::CreateFillerObjectAt(Address addr, int size,
310262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       ClearRecordedSlots mode) {
310362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (size == 0) return nullptr;
3104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject* filler = HeapObject::FromAddress(addr);
3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (size == kPointerSize) {
3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    filler->set_map_no_write_barrier(
3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Map*>(root(kOnePointerFillerMapRootIndex)));
3108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (size == 2 * kPointerSize) {
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    filler->set_map_no_write_barrier(
3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Map*>(root(kTwoPointerFillerMapRootIndex)));
3111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_GT(size, 2 * kPointerSize);
3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    filler->set_map_no_write_barrier(
3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Map*>(root(kFreeSpaceMapRootIndex)));
3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FreeSpace::cast(filler)->nobarrier_set_size(size);
3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
31173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (mode == ClearRecordedSlots::kYes) {
31183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ClearRecordedSlotRange(addr, addr + size);
31193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
3120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // At this point, we may be deserializing the heap from a snapshot, and
3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // none of the maps have been created yet and are NULL.
3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((filler->map() == NULL && !deserialization_complete_) ||
3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         filler->map()->IsMap());
312562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return filler;
3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CanMoveObjectStart(HeapObject* object) {
3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!FLAG_move_object_start) return false;
3131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Sampling heap profiler may have a reference to the object.
3133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (isolate()->heap_profiler()->is_sampling_allocations()) return false;
3134109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address address = object->address();
3136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lo_space()->Contains(object)) return false;
3138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
313913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // We can move the object start if the page was already swept.
314013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return Page::FromAddress(address)->SweepingDone();
3141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
314362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool Heap::IsImmovable(HeapObject* object) {
314462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  MemoryChunk* chunk = MemoryChunk::FromAddress(object->address());
314562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return chunk->NeverEvacuate() || chunk->owner()->identity() == LO_SPACE;
314662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
3147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
314862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::AdjustLiveBytes(HeapObject* object, int by) {
3149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // As long as the inspected object is black and we are currently not iterating
3150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the heap using HeapIterator, we can update the live byte count. We cannot
3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // update while using HeapIterator because the iterator is temporarily
3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // marking the whole object graph, without updating live bytes.
31533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (lo_space()->Contains(object)) {
31543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    lo_space()->AdjustLiveBytes(by);
31553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (!in_heap_iterator() &&
31563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             !mark_compact_collector()->sweeping_in_progress() &&
315762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             ObjectMarking::IsBlack(object)) {
315862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(MemoryChunk::FromAddress(object->address())->SweepingDone());
315962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    MemoryChunk::IncrementLiveBytes(object, by);
3160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object,
3165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         int elements_to_trim) {
316613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  CHECK_NOT_NULL(object);
316762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(CanMoveObjectStart(object));
3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!object->IsFixedTypedArrayBase());
3169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!object->IsByteArray());
3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize;
3171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int bytes_to_trim = elements_to_trim * element_size;
3172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = object->map();
3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For now this trick is only applied to objects in new and paged space.
3175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // In large object space the object's start must coincide with chunk
3176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and thus the trick is just not applicable.
3177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!lo_space()->Contains(object));
3178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(object->map() != fixed_cow_array_map());
3179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FixedArrayBase::kMapOffset == 0);
3181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize);
3182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize);
3183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int len = object->length();
3185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(elements_to_trim <= len);
3186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Calculate location of new array start.
3188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Address old_start = object->address();
3189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Address new_start = old_start + bytes_to_trim;
3190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Transfer the mark bits to their new location if the object is not within
3192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // a black area.
3193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!incremental_marking()->black_allocation() ||
319462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      !Marking::IsBlack(
319562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          ObjectMarking::MarkBitFrom(HeapObject::FromAddress(new_start)))) {
319662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    IncrementalMarking::TransferMark(this, object,
319762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     HeapObject::FromAddress(new_start));
3198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Technically in new space this write might be omitted (except for
3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // debug mode which iterates through the heap), but to play safer
3202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we still do it.
3203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CreateFillerObjectAt(old_start, bytes_to_trim, ClearRecordedSlots::kYes);
320462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
320562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Clear the mark bits of the black area that belongs now to the filler.
320662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // This is an optimization. The sweeper will release black fillers anyway.
320762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (incremental_marking()->black_allocation() &&
320862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(object))) {
320962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Page* page = Page::FromAddress(old_start);
321062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    page->markbits()->ClearRange(
321162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        page->AddressToMarkbitIndex(old_start),
321262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        page->AddressToMarkbitIndex(old_start + bytes_to_trim));
321362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
321462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
3215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize header of the trimmed array. Since left trimming is only
3216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // performed on pages which are not concurrently swept creating a filler
3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // object does not require synchronization.
3218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** former_start = HeapObject::RawField(object, 0);
3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int new_start_index = elements_to_trim * (element_size / kPointerSize);
3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  former_start[new_start_index] = map;
3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim);
3222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArrayBase* new_object =
3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FixedArrayBase::cast(HeapObject::FromAddress(new_start));
3225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Maintain consistency of live bytes during incremental marking
322762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  AdjustLiveBytes(new_object, -bytes_to_trim);
3228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3229bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Remove recorded slots for the new map and length offset.
3230bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ClearRecordedSlot(new_object, HeapObject::RawField(new_object, 0));
3231bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ClearRecordedSlot(new_object, HeapObject::RawField(
3232bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                    new_object, FixedArrayBase::kLengthOffset));
3233bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Notify the heap profiler of change in object layout.
3235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OnMoveEvent(new_object, object, new_object->Size());
3236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_object;
3237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) {
3240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int len = object->length();
3241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LE(elements_to_trim, len);
3242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_GE(elements_to_trim, 0);
3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int bytes_to_trim;
3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (object->IsFixedTypedArrayBase()) {
3246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstanceType type = object->map()->instance_type();
3247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bytes_to_trim =
3248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FixedTypedArrayBase::TypedArraySize(type, len) -
3249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FixedTypedArrayBase::TypedArraySize(type, len - elements_to_trim);
3250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (object->IsByteArray()) {
3251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int new_size = ByteArray::SizeFor(len - elements_to_trim);
3252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bytes_to_trim = ByteArray::SizeFor(len) - new_size;
3253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_GE(bytes_to_trim, 0);
3254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int element_size =
3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        object->IsFixedArray() ? kPointerSize : kDoubleSize;
3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bytes_to_trim = elements_to_trim * element_size;
3258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For now this trick is only applied to objects in new and paged space.
3262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(object->map() != fixed_cow_array_map());
3263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (bytes_to_trim == 0) {
3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // No need to create filler and update live bytes counters, just initialize
3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // header of the trimmed array.
3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    object->synchronized_set_length(len - elements_to_trim);
3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Calculate location of new array end.
3272109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Address old_end = object->address() + object->Size();
3273109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Address new_end = old_end - bytes_to_trim;
3274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Technically in new space this write might be omitted (except for
3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // debug mode which iterates through the heap), but to play safer
3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we still do it.
3278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not create a filler for objects in large object space.
3279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(hpayer): We should shrink the large object page if the size
3280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of the object changed significantly.
3281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!lo_space()->Contains(object)) {
328262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    HeapObject* filler =
328362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        CreateFillerObjectAt(new_end, bytes_to_trim, ClearRecordedSlots::kYes);
328462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_NOT_NULL(filler);
328562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Clear the mark bits of the black area that belongs now to the filler.
328662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // This is an optimization. The sweeper will release black fillers anyway.
328762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (incremental_marking()->black_allocation() &&
328862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        ObjectMarking::IsBlackOrGrey(filler)) {
328962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Page* page = Page::FromAddress(new_end);
329062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      page->markbits()->ClearRange(
329162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          page->AddressToMarkbitIndex(new_end),
329262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          page->AddressToMarkbitIndex(new_end + bytes_to_trim));
329362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize header of the trimmed array. We are storing the new length
3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // using release store after creating a filler for the left-over space to
3298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // avoid races with the sweeper thread.
3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object->synchronized_set_length(len - elements_to_trim);
3300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Maintain consistency of live bytes during incremental marking
330262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  AdjustLiveBytes(object, -bytes_to_trim);
3303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Notify the heap profiler of change in object layout. The array may not be
3305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // moved during GC, and size has to be adjusted nevertheless.
3306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapProfiler* profiler = isolate()->heap_profiler();
3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (profiler->is_tracking_allocations()) {
3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    profiler->UpdateObjectSizeEvent(object->address(), object->Size());
3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocationResult Heap::AllocateFixedTypedArrayWithExternalPointer(
3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int length, ExternalArrayType array_type, void* external_pointer,
3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PretenureFlag pretenure) {
3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int size = FixedTypedArrayBase::kHeaderSize;
3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space);
3321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->set_map_no_write_barrier(MapForFixedTypedArray(array_type));
3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(result);
3326c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  elements->set_base_pointer(Smi::kZero, SKIP_WRITE_BARRIER);
3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  elements->set_external_pointer(external_pointer, SKIP_WRITE_BARRIER);
3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  elements->set_length(length);
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return elements;
3330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ForFixedTypedArray(ExternalArrayType array_type, int* element_size,
3333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               ElementsKind* element_kind) {
3334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (array_type) {
3335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
3336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case kExternal##Type##Array:                          \
3337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *element_size = size;                               \
3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *element_kind = TYPE##_ELEMENTS;                    \
3339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
3340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(TYPED_ARRAY_CASE)
3342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef TYPED_ARRAY_CASE
3343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
3345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *element_size = 0;               // Bogus
3346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *element_kind = UINT8_ELEMENTS;  // Bogus
3347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFixedTypedArray(int length,
3353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               ExternalArrayType array_type,
3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               bool initialize,
3355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               PretenureFlag pretenure) {
3356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int element_size;
3357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ElementsKind elements_kind;
3358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ForFixedTypedArray(array_type, &element_size, &elements_kind);
3359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = OBJECT_POINTER_ALIGN(length * element_size +
3360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  FixedTypedArrayBase::kDataOffset);
3361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* object = nullptr;
3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(
3365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size, space,
3366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array_type == kExternalFloat64Array ? kDoubleAligned : kWordAligned);
3367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&object)) return allocation;
3368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  object->set_map_no_write_barrier(MapForFixedTypedArray(array_type));
3370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object);
3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  elements->set_base_pointer(elements, SKIP_WRITE_BARRIER);
3372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  elements->set_external_pointer(
3373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ExternalReference::fixed_typed_array_base_data_offset().address(),
3374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SKIP_WRITE_BARRIER);
3375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  elements->set_length(length);
3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (initialize) memset(elements->DataPtr(), 0, elements->DataSize());
3377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return elements;
3378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateCode(int object_size, bool immovable) {
3382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment));
3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(object_size, CODE_SPACE);
3384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
3387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (immovable) {
3388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Address address = result->address();
338962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    MemoryChunk* chunk = MemoryChunk::FromAddress(address);
3390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Code objects which should stay at a fixed address are allocated either
3391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // in the first page of code space (objects on the first page of each space
339262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // are never moved), in large object space, or (during snapshot creation)
339362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // the containing page is marked as immovable.
339462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!Heap::IsImmovable(result) &&
339562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        !code_space_->FirstPage()->Contains(address)) {
339662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (isolate()->serializer_enabled()) {
339762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        chunk->MarkNeverEvacuate();
339862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
339962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // Discard the first code allocation, which was on a page where it could
340062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // be moved.
340162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        CreateFillerObjectAt(result->address(), object_size,
340262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             ClearRecordedSlots::kNo);
340362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE);
340462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (!allocation.To(&result)) return allocation;
340562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        OnAllocationEvent(result, object_size);
340662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
3407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(code_map());
3411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* code = Code::cast(result);
3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsAligned(bit_cast<intptr_t>(code->address()), kCodeAlignment));
341313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(!memory_allocator()->code_range()->valid() ||
3414bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         memory_allocator()->code_range()->contains(code->address()) ||
3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         object_size <= code_space()->AreaSize());
3416c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  code->set_gc_metadata(Smi::kZero);
3417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code->set_ic_age(global_ic_age_);
3418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return code;
3419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyCode(Code* code) {
3423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation;
3424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate an object the same size as the code object.
3427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int obj_size = code->Size();
3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  allocation = AllocateRaw(obj_size, CODE_SPACE);
3429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
3430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy code object.
3432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address old_addr = code->address();
3433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address new_addr = result->address();
3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CopyBlock(new_addr, old_addr, obj_size);
3435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* new_code = Code::cast(result);
3436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Relocate the copy.
3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsAligned(bit_cast<intptr_t>(new_code->address()), kCodeAlignment));
343913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(!memory_allocator()->code_range()->valid() ||
3440bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         memory_allocator()->code_range()->contains(code->address()) ||
3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         obj_size <= code_space()->AreaSize());
3442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_code->Relocate(new_addr - old_addr);
34433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // We have to iterate over the object and process its pointers when black
34443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // allocation is on.
34453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  incremental_marking()->IterateBlackObject(new_code);
3446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Record all references to embedded objects in the new code object.
3447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RecordWritesIntoCode(new_code);
3448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_code;
3449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3451109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochAllocationResult Heap::CopyBytecodeArray(BytecodeArray* bytecode_array) {
3452109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int size = BytecodeArray::SizeFor(bytecode_array->length());
3453109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HeapObject* result = nullptr;
3454109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  {
3455109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
3456109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!allocation.To(&result)) return allocation;
3457109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3458109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3459109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  result->set_map_no_write_barrier(bytecode_array_map());
3460109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArray* copy = BytecodeArray::cast(result);
3461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_length(bytecode_array->length());
3462109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_frame_size(bytecode_array->frame_size());
3463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_parameter_count(bytecode_array->parameter_count());
3464109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_constant_pool(bytecode_array->constant_pool());
3465109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_handler_table(bytecode_array->handler_table());
3466109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_source_position_table(bytecode_array->source_position_table());
34673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  copy->set_interrupt_budget(bytecode_array->interrupt_budget());
3468f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  copy->set_osr_loop_nesting_level(bytecode_array->osr_loop_nesting_level());
346962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  copy->set_bytecode_age(bytecode_array->bytecode_age());
3470109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bytecode_array->CopyBytecodesTo(copy);
3471109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return copy;
3472109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
3473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::InitializeAllocationMemento(AllocationMemento* memento,
3475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       AllocationSite* allocation_site) {
3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  memento->set_map_no_write_barrier(allocation_memento_map());
3477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(allocation_site->map() == allocation_site_map());
3478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER);
3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_allocation_site_pretenuring) {
3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocation_site->IncrementMementoCreateCount();
3481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::Allocate(Map* map, AllocationSpace space,
3486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                AllocationSite* allocation_site) {
3487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(gc_state_ == NOT_IN_GC);
3488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(map->instance_type() != MAP_TYPE);
3489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = map->instance_size();
3490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (allocation_site != NULL) {
3491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size += AllocationMemento::kSize;
3492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(size, space);
3495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No need for write barrier since object is white and map is in old space.
3497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(map);
3498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (allocation_site != NULL) {
3499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
3500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<Address>(result) + map->instance_size());
3501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InitializeAllocationMemento(alloc_memento, allocation_site);
3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::InitializeJSObjectFromMap(JSObject* obj, FixedArray* properties,
3508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Map* map) {
3509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_properties(properties);
3510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->initialize_elements();
3511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(1240798): Initialize the object's body using valid initial values
3512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // according to the object's initial map.  For example, if the map's
3513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instance type is JS_ARRAY_TYPE, the length field should be initialized
3514c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // to a number (e.g. Smi::kZero) and the elements initialized to a
3515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // fixed array (e.g. Heap::empty_fixed_array()).  Currently, the object
3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // verification code has to cope with (temporarily) invalid objects.  See
3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for example, JSArray::JSArrayVerify).
3518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InitializeJSObjectBody(obj, map, JSObject::kHeaderSize);
3519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::InitializeJSObjectBody(JSObject* obj, Map* map, int start_offset) {
3523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (start_offset == map->instance_size()) return;
3524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LT(start_offset, map->instance_size());
3525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We cannot always fill with one_pointer_filler_map because objects
3527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // created from API functions expect their internal fields to be initialized
3528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // with undefined_value.
3529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Pre-allocated fields need to be initialized with undefined_value as well
3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // so that object accesses before the constructor completes (e.g. in the
3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // debugger) will not cause a crash.
3532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // In case of Array subclassing the |map| could already be transitioned
3534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to different elements kind from the initial map on which we track slack.
3535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool in_progress = map->IsInobjectSlackTrackingInProgress();
3536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Object* filler;
3537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (in_progress) {
3538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    filler = one_pointer_filler_map();
3539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    filler = undefined_value();
3541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  obj->InitializeBody(map, start_offset, Heap::undefined_value(), filler);
3543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (in_progress) {
3544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    map->FindRootMap()->InobjectSlackTrackingStep();
3545109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateJSObjectFromMap(
3550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Map* map, PretenureFlag pretenure, AllocationSite* allocation_site) {
3551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // JSFunctions should be allocated using AllocateFunction to be
3552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // properly initialized.
3553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(map->instance_type() != JS_FUNCTION_TYPE);
3554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Both types of global objects should be allocated using
3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // AllocateGlobalObject to be properly initialized.
3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(map->instance_type() != JS_GLOBAL_OBJECT_TYPE);
3558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the backing storage for the properties.
3560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* properties = empty_fixed_array();
3561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the JSObject.
3563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSObject* js_obj = nullptr;
3565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation = Allocate(map, space, allocation_site);
3566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&js_obj)) return allocation;
3567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize the JSObject.
3569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InitializeJSObjectFromMap(js_obj, properties, map);
3570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(js_obj->HasFastElements() || js_obj->HasFixedTypedArrayElements() ||
357113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch         js_obj->HasFastStringWrapperElements() ||
357213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch         js_obj->HasFastArgumentsElements());
3573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return js_obj;
3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateJSObject(JSFunction* constructor,
3578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        PretenureFlag pretenure,
3579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        AllocationSite* allocation_site) {
3580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(constructor->has_initial_map());
3581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the object based on the constructors initial map.
3583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation = AllocateJSObjectFromMap(
3584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      constructor->initial_map(), pretenure, allocation_site);
3585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
3586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Make sure result is NOT a global object if valid.
3587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!allocation.To(&obj) || !obj->IsJSGlobalObject());
3589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
3590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return allocation;
3591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
3595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Make the clone.
3596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = source->map();
3597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
359813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // We can only clone regexps, normal objects, api objects, errors or arrays.
359913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Copying anything else will break invariants.
3600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(map->instance_type() == JS_REGEXP_TYPE ||
3601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        map->instance_type() == JS_OBJECT_TYPE ||
360213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        map->instance_type() == JS_ERROR_TYPE ||
36033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        map->instance_type() == JS_ARRAY_TYPE ||
3604bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        map->instance_type() == JS_API_OBJECT_TYPE ||
36053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        map->instance_type() == JS_SPECIAL_API_OBJECT_TYPE);
3606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int object_size = map->instance_size();
3608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* clone = nullptr;
3609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type()));
3611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int adjusted_object_size =
3613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      site != NULL ? object_size + AllocationMemento::kSize : object_size;
3614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(adjusted_object_size, NEW_SPACE);
3615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!allocation.To(&clone)) return allocation;
3616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SLOW_DCHECK(InNewSpace(clone));
3618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Since we know the clone is allocated in new space, we can copy
3619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the contents without worrying about updating the write barrier.
3620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CopyBlock(clone->address(), source->address(), object_size);
3621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (site != NULL) {
3623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
3624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(clone) + object_size);
3625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InitializeAllocationMemento(alloc_memento, site);
3626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SLOW_DCHECK(JSObject::cast(clone)->GetElementsKind() ==
3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              source->GetElementsKind());
3630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
3631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray* properties = FixedArray::cast(source->properties());
3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update elements if necessary.
3633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (elements->length() > 0) {
3634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedArrayBase* elem = nullptr;
3635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
3636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllocationResult allocation;
3637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (elements->map() == fixed_cow_array_map()) {
3638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        allocation = FixedArray::cast(elements);
3639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (source->HasFastDoubleElements()) {
3640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        allocation = CopyFixedDoubleArray(FixedDoubleArray::cast(elements));
3641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
3642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        allocation = CopyFixedArray(FixedArray::cast(elements));
3643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!allocation.To(&elem)) return allocation;
3645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    JSObject::cast(clone)->set_elements(elem, SKIP_WRITE_BARRIER);
3647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update properties if necessary.
3649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (properties->length() > 0) {
3650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedArray* prop = nullptr;
3651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
3652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllocationResult allocation = CopyFixedArray(properties);
3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!allocation.To(&prop)) return allocation;
3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    JSObject::cast(clone)->set_properties(prop, SKIP_WRITE_BARRIER);
3656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return the new clone.
3658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return clone;
3659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteOneByteData(Vector<const char> vector, uint8_t* chars,
3663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    int len) {
3664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Only works for one byte strings.
3665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(vector.length() == len);
3666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemCopy(chars, vector.start(), len);
3667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteTwoByteData(Vector<const char> vector, uint16_t* chars,
3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    int len) {
3671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const uint8_t* stream = reinterpret_cast<const uint8_t*>(vector.start());
3672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t stream_length = vector.length();
3673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (stream_length != 0) {
3674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t consumed = 0;
3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t c = unibrow::Utf8::ValueOf(stream, stream_length, &consumed);
3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(c != unibrow::Utf8::kBadChar);
3677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(consumed <= stream_length);
3678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream_length -= consumed;
3679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream += consumed;
3680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
3681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      len -= 2;
3682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (len < 0) break;
3683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *chars++ = unibrow::Utf16::LeadSurrogate(c);
3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *chars++ = unibrow::Utf16::TrailSurrogate(c);
3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      len -= 1;
3687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (len < 0) break;
3688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *chars++ = c;
3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(stream_length == 0);
3692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(len == 0);
3693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteOneByteData(String* s, uint8_t* chars, int len) {
3697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(s->length() == len);
3698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::WriteToFlat(s, chars, 0, len);
3699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteTwoByteData(String* s, uint16_t* chars, int len) {
3703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(s->length() == len);
3704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::WriteToFlat(s, chars, 0, len);
3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <bool is_one_byte, typename T>
3709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateInternalizedStringImpl(T t, int chars,
3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                      uint32_t hash_field) {
3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(chars >= 0);
3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute map and object size.
3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size;
3714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map;
3715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_LE(0, chars);
3717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_GE(String::kMaxLength, chars);
3718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_one_byte) {
3719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    map = one_byte_internalized_string_map();
3720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size = SeqOneByteString::SizeFor(chars);
3721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    map = internalized_string_map();
3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size = SeqTwoByteString::SizeFor(chars);
3724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate string.
3727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
3730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(map);
3734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set length and hash fields of the allocated string.
3735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String* answer = String::cast(result);
3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  answer->set_length(chars);
3737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  answer->set_hash_field(hash_field);
3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(size, answer->Size());
3740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_one_byte) {
3742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars);
3743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars);
3745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return answer;
3747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Need explicit instantiations.
3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate AllocationResult Heap::AllocateInternalizedStringImpl<true>(String*,
3752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                     int,
3753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                     uint32_t);
3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate AllocationResult Heap::AllocateInternalizedStringImpl<false>(String*,
3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                      int,
3756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                      uint32_t);
3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate AllocationResult Heap::AllocateInternalizedStringImpl<false>(
3758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Vector<const char>, int, uint32_t);
3759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawOneByteString(int length,
3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                PretenureFlag pretenure) {
3763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_LE(0, length);
3764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_GE(String::kMaxLength, length);
3765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = SeqOneByteString::SizeFor(length);
3766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(size <= SeqOneByteString::kMaxSize);
3767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space);
3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partially initialize the object.
3776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(one_byte_string_map());
3777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::cast(result)->set_length(length);
3778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::cast(result)->set_hash_field(String::kEmptyHashField);
3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(size, HeapObject::cast(result)->Size());
3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawTwoByteString(int length,
3786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                PretenureFlag pretenure) {
3787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_LE(0, length);
3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_GE(String::kMaxLength, length);
3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = SeqTwoByteString::SizeFor(length);
3790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(size <= SeqTwoByteString::kMaxSize);
3791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space);
3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partially initialize the object.
3800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(string_map());
3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::cast(result)->set_length(length);
3802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::cast(result)->set_hash_field(String::kEmptyHashField);
3803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(size, HeapObject::cast(result)->Size());
3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateEmptyFixedArray() {
3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = FixedArray::SizeFor(0);
3810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
3813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize the object.
3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(fixed_array_map());
3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray::cast(result)->set_length(0);
3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3821f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAllocationResult Heap::AllocateEmptyScopeInfo() {
3822f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int size = FixedArray::SizeFor(0);
3823f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  HeapObject* result = nullptr;
3824f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
3825f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
3826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!allocation.To(&result)) return allocation;
3827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Initialize the object.
3829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  result->set_map_no_write_barrier(scope_info_map());
3830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FixedArray::cast(result)->set_length(0);
3831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return result;
3832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
3833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyAndTenureFixedCOWArray(FixedArray* src) {
3835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!InNewSpace(src)) {
3836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return src;
3837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int len = src->length();
3840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedArray(len, TENURED);
3843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
3844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_map_no_write_barrier(fixed_array_map());
3846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray* result = FixedArray::cast(obj);
3847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_length(len);
3848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy the content.
3850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_gc;
3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
3853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mvstanton): The map is set twice because of protection against calling
3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // set() on a COW FixedArray. Issue v8:3221 created to track this, and
3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we might then be able to remove this whole method.
3857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject::cast(obj)->set_map_no_write_barrier(fixed_cow_array_map());
3858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateEmptyFixedTypedArray(
3863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ExternalArrayType array_type) {
3864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AllocateFixedTypedArray(0, array_type, false, TENURED);
3865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocationResult Heap::CopyFixedArrayAndGrow(FixedArray* src, int grow_by,
3869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             PretenureFlag pretenure) {
3870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int old_len = src->length();
3871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_len = old_len + grow_by;
3872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(new_len >= old_len);
3873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
3875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure);
3876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!allocation.To(&obj)) return allocation;
3877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  obj->set_map_no_write_barrier(fixed_array_map());
3880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* result = FixedArray::cast(obj);
3881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->set_length(new_len);
3882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy the content.
3884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_gc;
3885109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteBarrierMode mode = obj->GetWriteBarrierMode(no_gc);
3886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < old_len; i++) result->set(i, src->get(i), mode);
3887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MemsetPointer(result->data_start() + old_len, undefined_value(), grow_by);
3888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
3889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3891109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochAllocationResult Heap::CopyFixedArrayUpTo(FixedArray* src, int new_len,
3892109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                          PretenureFlag pretenure) {
3893109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (new_len == 0) return empty_fixed_array();
3894109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3895109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_LE(new_len, src->length());
3896109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3897109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HeapObject* obj = nullptr;
3898109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  {
3899109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure);
3900109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!allocation.To(&obj)) return allocation;
3901109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3902109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  obj->set_map_no_write_barrier(fixed_array_map());
3903109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3904109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FixedArray* result = FixedArray::cast(obj);
3905109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  result->set_length(new_len);
3906109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3907109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Copy the content.
3908109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DisallowHeapAllocation no_gc;
3909109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3910109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < new_len; i++) result->set(i, src->get(i), mode);
3911109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return result;
3912109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
3913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
3915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int len = src->length();
3916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED);
3919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
3920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3921109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  obj->set_map_no_write_barrier(map);
3922f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FixedArray* result = FixedArray::cast(obj);
3924f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DisallowHeapAllocation no_gc;
3925f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Eliminate the write barrier if possible.
3928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (mode == SKIP_WRITE_BARRIER) {
3929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CopyBlock(obj->address() + kPointerSize, src->address() + kPointerSize,
3930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              FixedArray::SizeFor(len) - kPointerSize);
3931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return obj;
3932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Slow case: Just copy the content one-by-one.
3935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  result->set_length(len);
3936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
3937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src,
3942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                   Map* map) {
3943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int len = src->length();
3944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedDoubleArray(len, NOT_TENURED);
3947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
3948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_map_no_write_barrier(map);
3950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CopyBlock(obj->address() + FixedDoubleArray::kLengthOffset,
3951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            src->address() + FixedDoubleArray::kLengthOffset,
3952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset);
3953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj;
3954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawFixedArray(int length,
3958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             PretenureFlag pretenure) {
3959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length < 0 || length > FixedArray::kMaxLength) {
3960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
3961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = FixedArray::SizeFor(length);
3963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3965f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AllocationResult result = AllocateRaw(size, space);
3966f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!result.IsRetry() && size > kMaxRegularHeapObjectSize &&
3967f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      FLAG_use_marking_progress_bar) {
3968f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    MemoryChunk* chunk =
3969f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        MemoryChunk::FromAddress(result.ToObjectChecked()->address());
3970f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    chunk->SetFlag(MemoryChunk::HAS_PROGRESS_BAR);
3971f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3972f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return result;
3973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFixedArrayWithFiller(int length,
3977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                    PretenureFlag pretenure,
3978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                    Object* filler) {
3979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(length >= 0);
3980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(empty_fixed_array()->IsFixedArray());
3981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length == 0) return empty_fixed_array();
3982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(filler));
3984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedArray(length, pretenure);
3987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(fixed_array_map());
3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray* array = FixedArray::cast(result);
3992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array->set_length(length);
3993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemsetPointer(array->data_start(), filler, length);
3994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return array;
3995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return AllocateFixedArrayWithFiller(length, pretenure, undefined_value());
4000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateUninitializedFixedArray(int length) {
4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length == 0) return empty_fixed_array();
4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
4007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
4008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedArray(length, NOT_TENURED);
4009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
4010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_map_no_write_barrier(fixed_array_map());
4013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray::cast(obj)->set_length(length);
4014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj;
4015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateUninitializedFixedDoubleArray(
4019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int length, PretenureFlag pretenure) {
4020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length == 0) return empty_fixed_array();
4021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* elements = nullptr;
4023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation = AllocateRawFixedDoubleArray(length, pretenure);
4024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&elements)) return allocation;
4025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  elements->set_map_no_write_barrier(fixed_double_array_map());
4027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedDoubleArray::cast(elements)->set_length(length);
4028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return elements;
4029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawFixedDoubleArray(int length,
4033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                   PretenureFlag pretenure) {
4034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length < 0 || length > FixedDoubleArray::kMaxLength) {
4035bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
4036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = FixedDoubleArray::SizeFor(length);
4038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
4039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* object = nullptr;
4041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
4042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space, kDoubleAligned);
4043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&object)) return allocation;
4044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return object;
4047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateSymbol() {
4051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Statically ensure that it is safe to allocate symbols in paged spaces.
4052f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  STATIC_ASSERT(Symbol::kSize <= kMaxRegularHeapObjectSize);
4053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
4055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(Symbol::kSize, OLD_SPACE);
4056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
4057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(symbol_map());
4059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Generate a random hash value.
4061c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int hash = isolate()->GenerateIdentityHash(Name::kHashBitMask);
4062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Symbol::cast(result)
4064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ->set_hash_field(Name::kIsNotArrayIndexMask | (hash << Name::kHashShift));
4065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Symbol::cast(result)->set_name(undefined_value());
4066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Symbol::cast(result)->set_flags(0);
4067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!Symbol::cast(result)->is_private());
4069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
4070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateStruct(InstanceType type) {
4074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map;
4075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (type) {
4076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define MAKE_CASE(NAME, Name, name) \
4077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case NAME##_TYPE:                 \
4078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    map = name##_map();             \
4079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    break;
4080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STRUCT_LIST(MAKE_CASE)
4081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef MAKE_CASE
4082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
4083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
4084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return exception();
4085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = map->instance_size();
4087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Struct* result = nullptr;
4088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
4089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = Allocate(map, OLD_SPACE);
4090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
4091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->InitializeBody(size);
4093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
4094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MakeHeapIterable() {
409862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  mark_compact_collector()->EnsureSweepingCompleted();
4099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic double ComputeMutatorUtilization(double mutator_speed, double gc_speed) {
4103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double kMinMutatorUtilization = 0.0;
4104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double kConservativeGcSpeedInBytesPerMillisecond = 200000;
4105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mutator_speed == 0) return kMinMutatorUtilization;
4106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (gc_speed == 0) gc_speed = kConservativeGcSpeedInBytesPerMillisecond;
4107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Derivation:
4108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // mutator_utilization = mutator_time / (mutator_time + gc_time)
4109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // mutator_time = 1 / mutator_speed
4110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // gc_time = 1 / gc_speed
4111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // mutator_utilization = (1 / mutator_speed) /
4112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //                       (1 / mutator_speed + 1 / gc_speed)
4113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // mutator_utilization = gc_speed / (mutator_speed + gc_speed)
4114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return gc_speed / (mutator_speed + gc_speed);
4115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble Heap::YoungGenerationMutatorUtilization() {
4119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double mutator_speed = static_cast<double>(
4120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond());
41213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  double gc_speed =
41223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      tracer()->ScavengeSpeedInBytesPerMillisecond(kForSurvivedObjects);
4123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double result = ComputeMutatorUtilization(mutator_speed, gc_speed);
4124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_mutator_utilization) {
4125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    isolate()->PrintWithTimestamp(
4126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        "Young generation mutator utilization = %.3f ("
4127f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        "mutator_speed=%.f, gc_speed=%.f)\n",
4128f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        result, mutator_speed, gc_speed);
4129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
4131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble Heap::OldGenerationMutatorUtilization() {
4135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double mutator_speed = static_cast<double>(
4136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer()->OldGenerationAllocationThroughputInBytesPerMillisecond());
4137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double gc_speed = static_cast<double>(
4138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer()->CombinedMarkCompactSpeedInBytesPerMillisecond());
4139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double result = ComputeMutatorUtilization(mutator_speed, gc_speed);
4140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_mutator_utilization) {
4141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    isolate()->PrintWithTimestamp(
4142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        "Old generation mutator utilization = %.3f ("
4143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        "mutator_speed=%.f, gc_speed=%.f)\n",
4144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        result, mutator_speed, gc_speed);
4145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
4147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::HasLowYoungGenerationAllocationRate() {
4151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double high_mutator_utilization = 0.993;
4152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return YoungGenerationMutatorUtilization() > high_mutator_utilization;
4153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::HasLowOldGenerationAllocationRate() {
4157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double high_mutator_utilization = 0.993;
4158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return OldGenerationMutatorUtilization() > high_mutator_utilization;
4159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
4160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::HasLowAllocationRate() {
4163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HasLowYoungGenerationAllocationRate() &&
4164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         HasLowOldGenerationAllocationRate();
4165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
4166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::HasHighFragmentation() {
4169c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t used = PromotedSpaceSizeOfObjects();
4170c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t committed = CommittedOldGenerationMemory();
4171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HasHighFragmentation(used, committed);
4172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4174c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool Heap::HasHighFragmentation(size_t used, size_t committed) {
4175c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const size_t kSlack = 16 * MB;
4176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Fragmentation is high if committed > 2 * used + kSlack.
4177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Rewrite the exression to avoid overflow.
4178c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_GE(committed, used);
4179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return committed - used > used + kSlack;
4180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool Heap::ShouldOptimizeForMemoryUsage() {
4183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return FLAG_optimize_for_size || isolate()->IsIsolateInBackground() ||
4184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         HighMemoryPressure() || IsLowMemoryDevice();
4185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
4186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
4187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid Heap::ActivateMemoryReducerIfNeeded() {
4188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Activate memory reducer when switching to background if
4189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // - there was no mark compact since the start.
4190109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // - the committed memory can be potentially reduced.
4191109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // 2 pages for the old, code, and map space + 1 page for new space.
4192109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int kMinCommittedMemory = 7 * Page::kPageSize;
4193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory &&
4194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate()->IsIsolateInBackground()) {
4195109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    MemoryReducer::Event event;
4196109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    event.type = MemoryReducer::kPossibleGarbage;
4197109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    event.time_ms = MonotonicallyIncreasingTimeInMs();
4198109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    memory_reducer_->NotifyPossibleGarbage(event);
4199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
4201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ReduceNewSpaceSize() {
4203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(ulan): Unify this constant with the similar constant in
4204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // GCIdleTimeHandler once the change is merged to 4.5.
4205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const size_t kLowAllocationThroughput = 1000;
42063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const double allocation_throughput =
4207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer()->CurrentAllocationThroughputInBytesPerMillisecond();
4208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_predictable) return;
4210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (ShouldReduceMemory() ||
4212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ((allocation_throughput != 0) &&
4213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       (allocation_throughput < kLowAllocationThroughput))) {
4214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    new_space_->Shrink();
4215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UncommitFromSpace();
4216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4219f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Heap::FinalizeIncrementalMarkingIfComplete(
4220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    GarbageCollectionReason gc_reason) {
4221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incremental_marking()->IsMarking() &&
4222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      (incremental_marking()->IsReadyToOverApproximateWeakClosure() ||
4223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       (!incremental_marking()->finalize_marking_completed() &&
422462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        mark_compact_collector()->marking_deque()->IsEmpty() &&
422562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        local_embedder_heap_tracer()->ShouldFinalizeIncrementalMarking()))) {
4226f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    FinalizeIncrementalMarking(gc_reason);
422762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (incremental_marking()->IsComplete() ||
422862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             (mark_compact_collector()->marking_deque()->IsEmpty() &&
422962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              local_embedder_heap_tracer()
423062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  ->ShouldFinalizeIncrementalMarking())) {
4231f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    CollectAllGarbage(current_gc_flags_, gc_reason);
4232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool Heap::TryFinalizeIdleIncrementalMarking(
4236f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    double idle_time_in_ms, GarbageCollectionReason gc_reason) {
4237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t size_of_objects = static_cast<size_t>(SizeOfObjects());
42383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  double final_incremental_mark_compact_speed_in_bytes_per_ms =
42393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond();
4240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incremental_marking()->IsReadyToOverApproximateWeakClosure() ||
4241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      (!incremental_marking()->finalize_marking_completed() &&
424262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       mark_compact_collector()->marking_deque()->IsEmpty() &&
424362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       local_embedder_heap_tracer()->ShouldFinalizeIncrementalMarking() &&
4244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       gc_idle_time_handler_->ShouldDoOverApproximateWeakClosure(
42453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           idle_time_in_ms))) {
4246f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    FinalizeIncrementalMarking(gc_reason);
4247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
4248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (incremental_marking()->IsComplete() ||
424962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             (mark_compact_collector()->marking_deque()->IsEmpty() &&
425062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              local_embedder_heap_tracer()
425162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  ->ShouldFinalizeIncrementalMarking() &&
4252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              gc_idle_time_handler_->ShouldDoFinalIncrementalMarkCompact(
42533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  idle_time_in_ms, size_of_objects,
4254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  final_incremental_mark_compact_speed_in_bytes_per_ms))) {
4255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    CollectAllGarbage(current_gc_flags_, gc_reason);
4256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
4257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
4259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
42613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::RegisterReservationsForBlackAllocation(Reservation* reservations) {
42623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // TODO(hpayer): We do not have to iterate reservations on black objects
42633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // for marking. We just have to execute the special visiting side effect
42643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // code that adds objects to global data structures, e.g. for array buffers.
42653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
42663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (incremental_marking()->black_allocation()) {
426762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Iterate black objects in old space, code space, map space, and large
426862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // object space for side effects.
4269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) {
42703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      const Heap::Reservation& res = reservations[i];
42713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      for (auto& chunk : res) {
42723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Address addr = chunk.start;
42733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        while (addr < chunk.end) {
42743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          HeapObject* obj = HeapObject::FromAddress(addr);
427562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          // There might be grey objects due to black to grey transitions in
427662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          // incremental marking. E.g. see VisitNativeContextIncremental.
427762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          DCHECK(ObjectMarking::IsBlackOrGrey(obj));
427862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          if (ObjectMarking::IsBlack(obj)) {
427962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            incremental_marking()->IterateBlackObject(obj);
428062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          }
42813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          addr += obj->Size();
42823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
42833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
42843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
42853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
42863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
4287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
428862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::NotifyObjectLayoutChange(HeapObject* object,
428962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    const DisallowHeapAllocation&) {
429062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (FLAG_incremental_marking && incremental_marking()->IsMarking()) {
429162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    incremental_marking()->MarkGrey(this, object);
429262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
429362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#ifdef VERIFY_HEAP
429462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(pending_layout_change_object_ == nullptr);
429562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  pending_layout_change_object_ = object;
429662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#endif
429762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
429862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
429962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#ifdef VERIFY_HEAP
430062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::VerifyObjectLayoutChange(HeapObject* object, Map* new_map) {
430162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (pending_layout_change_object_ == nullptr) {
430262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(!object->IsJSObject() ||
430362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           !object->map()->TransitionRequiresSynchronizationWithGC(new_map));
430462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
430562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_EQ(pending_layout_change_object_, object);
430662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    pending_layout_change_object_ = nullptr;
430762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
430862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
430962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#endif
431062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
4311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGCIdleTimeHeapState Heap::ComputeHeapState() {
4312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCIdleTimeHeapState heap_state;
4313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.contexts_disposed = contexts_disposed_;
4314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  heap_state.contexts_disposal_rate =
4315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      tracer()->ContextDisposalRateInMilliseconds();
4316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects());
4317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
4318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return heap_state;
4319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::PerformIdleTimeAction(GCIdleTimeAction action,
4323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 GCIdleTimeHeapState heap_state,
4324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 double deadline_in_ms) {
4325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool result = false;
4326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (action.type) {
4327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DONE:
4328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result = true;
4329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case DO_INCREMENTAL_STEP: {
4331f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      const double remaining_idle_time_in_ms =
4332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          incremental_marking()->AdvanceIncrementalMarking(
4333f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              deadline_in_ms, IncrementalMarking::NO_GC_VIA_STACK_GUARD,
4334f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              IncrementalMarking::FORCE_COMPLETION, StepOrigin::kTask);
4335f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (remaining_idle_time_in_ms > 0.0) {
4336f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        TryFinalizeIdleIncrementalMarking(
4337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            remaining_idle_time_in_ms,
4338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            GarbageCollectionReason::kFinalizeMarkingViaTask);
4339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
4340f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      result = incremental_marking()->IsStopped();
4341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
4343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DO_FULL_GC: {
4344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(contexts_disposed_ > 0);
4345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HistogramTimerScope scope(isolate_->counters()->gc_context());
4346109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      TRACE_EVENT0("v8", "V8.GCContext");
4347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CollectAllGarbage(kNoGCFlags, GarbageCollectionReason::kContextDisposal);
4348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DO_NOTHING:
4351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
4355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::IdleNotificationEpilogue(GCIdleTimeAction action,
4359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    GCIdleTimeHeapState heap_state,
4360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    double start_ms, double deadline_in_ms) {
4361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double idle_time_in_ms = deadline_in_ms - start_ms;
4362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  double current_time = MonotonicallyIncreasingTimeInMs();
4363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  last_idle_notification_time_ = current_time;
4364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  double deadline_difference = deadline_in_ms - current_time;
4365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  contexts_disposed_ = 0;
4367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
4369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<int>(idle_time_in_ms));
4370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (deadline_in_ms - start_ms >
4372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      GCIdleTimeHandler::kMaxFrameRenderingIdleTime) {
4373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int committed_memory = static_cast<int>(CommittedMemory() / KB);
4374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int used_memory = static_cast<int>(heap_state.size_of_objects / KB);
4375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->counters()->aggregated_memory_heap_committed()->AddSample(
4376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        start_ms, committed_memory);
4377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->counters()->aggregated_memory_heap_used()->AddSample(
4378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        start_ms, used_memory);
4379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (deadline_difference >= 0) {
4382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (action.type != DONE && action.type != DO_NOTHING) {
4383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate()->counters()->gc_idle_time_limit_undershot()->AddSample(
4384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          static_cast<int>(deadline_difference));
4385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
4386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate()->counters()->gc_idle_time_limit_overshot()->AddSample(
4388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        static_cast<int>(-deadline_difference));
4389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if ((FLAG_trace_idle_notification && action.type > DO_NOTHING) ||
4392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FLAG_trace_idle_notification_verbose) {
4393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    isolate_->PrintWithTimestamp(
4394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        "Idle notification: requested idle time %.2f ms, used idle time %.2f "
4395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        "ms, deadline usage %.2f ms [",
4396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        idle_time_in_ms, idle_time_in_ms - deadline_difference,
4397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        deadline_difference);
4398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    action.Print();
4399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF("]");
4400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (FLAG_trace_idle_notification_verbose) {
4401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      PrintF("[");
4402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      heap_state.Print();
4403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      PrintF("]");
4404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
4405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF("\n");
4406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble Heap::MonotonicallyIncreasingTimeInMs() {
4411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
4412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         static_cast<double>(base::Time::kMillisecondsPerSecond);
4413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::IdleNotification(int idle_time_in_ms) {
4417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return IdleNotification(
4418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() +
4419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      (static_cast<double>(idle_time_in_ms) /
4420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       static_cast<double>(base::Time::kMillisecondsPerSecond)));
4421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::IdleNotification(double deadline_in_seconds) {
4425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(HasBeenSetUp());
4426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double deadline_in_ms =
4427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      deadline_in_seconds *
4428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<double>(base::Time::kMillisecondsPerSecond);
4429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HistogramTimerScope idle_notification_scope(
4430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_->counters()->gc_idle_notification());
4431109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE_EVENT0("v8", "V8.GCIdleNotification");
4432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double start_ms = MonotonicallyIncreasingTimeInMs();
4433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double idle_time_in_ms = deadline_in_ms - start_ms;
4434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer()->SampleAllocation(start_ms, NewSpaceAllocationCounter(),
4436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             OldGenerationAllocationCounter());
4437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCIdleTimeHeapState heap_state = ComputeHeapState();
4439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCIdleTimeAction action =
4441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      gc_idle_time_handler_->Compute(idle_time_in_ms, heap_state);
4442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms);
4444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IdleNotificationEpilogue(action, heap_state, start_ms, deadline_in_ms);
4446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
4447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Heap::RecentIdleNotificationHappened() {
4451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return (last_idle_notification_time_ +
4452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          GCIdleTimeHandler::kMaxScheduledIdleTime) >
4453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         MonotonicallyIncreasingTimeInMs();
4454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
4455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
44563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochclass MemoryPressureInterruptTask : public CancelableTask {
44573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch public:
44583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  explicit MemoryPressureInterruptTask(Heap* heap)
44593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      : CancelableTask(heap->isolate()), heap_(heap) {}
44603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
44613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  virtual ~MemoryPressureInterruptTask() {}
44623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
44633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch private:
44643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // v8::internal::CancelableTask overrides.
44653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void RunInternal() override { heap_->CheckMemoryPressure(); }
44663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
44673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Heap* heap_;
44683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(MemoryPressureInterruptTask);
44693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch};
44703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
44713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::CheckMemoryPressure() {
4472f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (HighMemoryPressure()) {
4473f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (isolate()->concurrent_recompilation_enabled()) {
4474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // The optimizing compiler may be unnecessarily holding on to memory.
4475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DisallowHeapAllocation no_recursive_gc;
4476c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      isolate()->optimizing_compile_dispatcher()->Flush(
4477c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          OptimizingCompileDispatcher::BlockingBehavior::kDontBlock);
4478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
4479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
44803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (memory_pressure_level_.Value() == MemoryPressureLevel::kCritical) {
4481f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    CollectGarbageOnMemoryPressure();
44823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (memory_pressure_level_.Value() == MemoryPressureLevel::kModerate) {
44833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (FLAG_incremental_marking && incremental_marking()->IsStopped()) {
4484f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      StartIncrementalMarking(kReduceMemoryFootprintMask,
4485f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              GarbageCollectionReason::kMemoryPressure);
44863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
44873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
44883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  MemoryReducer::Event event;
44893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  event.type = MemoryReducer::kPossibleGarbage;
44903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  event.time_ms = MonotonicallyIncreasingTimeInMs();
44913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  memory_reducer_->NotifyPossibleGarbage(event);
44923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
44933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4494f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Heap::CollectGarbageOnMemoryPressure() {
449513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const int kGarbageThresholdInBytes = 8 * MB;
449613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const double kGarbageThresholdAsFractionOfTotalMemory = 0.1;
449713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // This constant is the maximum response time in RAIL performance model.
449813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const double kMaxMemoryPressurePauseMs = 100;
449913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
450013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  double start = MonotonicallyIncreasingTimeInMs();
45013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CollectAllGarbage(kReduceMemoryFootprintMask | kAbortIncrementalMarkingMask,
4502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                    GarbageCollectionReason::kMemoryPressure,
4503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                    kGCCallbackFlagCollectAllAvailableGarbage);
450413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  double end = MonotonicallyIncreasingTimeInMs();
450513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
450613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Estimate how much memory we can free.
450713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int64_t potential_garbage =
450813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      (CommittedMemory() - SizeOfObjects()) + external_memory_;
450913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // If we can potentially free large amount of memory, then start GC right
451013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // away instead of waiting for memory reducer.
451113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (potential_garbage >= kGarbageThresholdInBytes &&
451213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      potential_garbage >=
451313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          CommittedMemory() * kGarbageThresholdAsFractionOfTotalMemory) {
451413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // If we spent less than half of the time budget, then perform full GC
451513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Otherwise, start incremental marking.
451613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (end - start < kMaxMemoryPressurePauseMs / 2) {
451713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      CollectAllGarbage(
4518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          kReduceMemoryFootprintMask | kAbortIncrementalMarkingMask,
4519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          GarbageCollectionReason::kMemoryPressure,
452013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          kGCCallbackFlagCollectAllAvailableGarbage);
452113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } else {
452213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (FLAG_incremental_marking && incremental_marking()->IsStopped()) {
4523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        StartIncrementalMarking(kReduceMemoryFootprintMask,
4524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                GarbageCollectionReason::kMemoryPressure);
452513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
452613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
452713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
45283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
45293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
45303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::MemoryPressureNotification(MemoryPressureLevel level,
45313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                      bool is_isolate_locked) {
45323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  MemoryPressureLevel previous = memory_pressure_level_.Value();
45333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  memory_pressure_level_.SetValue(level);
45343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if ((previous != MemoryPressureLevel::kCritical &&
45353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch       level == MemoryPressureLevel::kCritical) ||
45363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      (previous == MemoryPressureLevel::kNone &&
45373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch       level == MemoryPressureLevel::kModerate)) {
45383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (is_isolate_locked) {
45393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CheckMemoryPressure();
45403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else {
45413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ExecutionAccess access(isolate());
45423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      isolate()->stack_guard()->RequestGC();
45433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      V8::GetCurrentPlatform()->CallOnForegroundThread(
45443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          reinterpret_cast<v8::Isolate*>(isolate()),
45453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          new MemoryPressureInterruptTask(this));
45463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
45473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
45483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
4549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
455062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::SetOutOfMemoryCallback(v8::debug::OutOfMemoryCallback callback,
455162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  void* data) {
455262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  out_of_memory_callback_ = callback;
455362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  out_of_memory_callback_data_ = data;
455462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
455562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
455662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::InvokeOutOfMemoryCallback() {
455762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (out_of_memory_callback_) {
455862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    out_of_memory_callback_(out_of_memory_callback_data_);
455962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
456062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
456162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
456213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Heap::CollectCodeStatistics() {
4563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CodeStatistics::ResetCodeAndMetadataStatistics(isolate());
456413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // We do not look for code in new space, or map space.  If code
456513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // somehow ends up in those spaces, we would miss it here.
4566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CodeStatistics::CollectCodeStatistics(code_space_, isolate());
4567f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CodeStatistics::CollectCodeStatistics(old_space_, isolate());
4568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CodeStatistics::CollectCodeStatistics(lo_space_, isolate());
456913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
457013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
4571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
4572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::Print() {
4574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return;
4575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate()->PrintStack(stdout);
4576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllSpaces spaces(this);
4577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
4578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    space->Print();
4579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportCodeStatistics(const char* title) {
4584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF(">>>>>> Code Stats (%s) >>>>>>\n", title);
458513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  CollectCodeStatistics();
4586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CodeStatistics::ReportCodeStatistics(isolate());
4587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This function expects that NewSpace's allocated objects histogram is
4591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// populated (via a call to CollectStatistics or else as a side effect of a
4592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// just-completed scavenge collection).
4593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportHeapStatistics(const char* title) {
4594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  USE(title);
4595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF(">>>>>> =============== %s (%d) =============== >>>>>>\n", title,
4596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         gc_count_);
4597bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrintF("old_generation_allocation_limit_ %" V8PRIdPTR "\n",
4598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         old_generation_allocation_limit_);
4599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("\n");
4601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles(isolate_));
4602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->global_handles()->PrintStats();
4603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("\n");
4604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Heap statistics : ");
4606bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  memory_allocator()->ReportStatistics();
4607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("To space : ");
4608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_space_->ReportStatistics();
4609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintF("Old space : ");
4610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  old_space_->ReportStatistics();
4611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Code space : ");
4612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_space_->ReportStatistics();
4613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Map space : ");
4614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map_space_->ReportStatistics();
4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Large object space : ");
4616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  lo_space_->ReportStatistics();
4617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF(">>>>>> ========================================= >>>>>>\n");
4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
4621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4622f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochconst char* Heap::GarbageCollectionReasonToString(
4623f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    GarbageCollectionReason gc_reason) {
4624f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (gc_reason) {
4625f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kAllocationFailure:
4626f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "allocation failure";
4627f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kAllocationLimit:
4628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "allocation limit";
4629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kContextDisposal:
4630f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "context disposal";
4631f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kCountersExtension:
4632f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "counters extension";
4633f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kDebugger:
4634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "debugger";
4635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kDeserializer:
4636f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "deserialize";
4637f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kExternalMemoryPressure:
4638f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "external memory pressure";
4639f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kFinalizeMarkingViaStackGuard:
4640f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "finalize incremental marking via stack guard";
4641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kFinalizeMarkingViaTask:
4642f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "finalize incremental marking via task";
4643f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kFullHashtable:
4644f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "full hash-table";
4645f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kHeapProfiler:
4646f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "heap profiler";
4647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kIdleTask:
4648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "idle task";
4649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kLastResort:
4650f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "last resort";
4651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kLowMemoryNotification:
4652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "low memory notification";
4653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kMakeHeapIterable:
4654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "make heap iterable";
4655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kMemoryPressure:
4656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "memory pressure";
4657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kMemoryReducer:
4658f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "memory reducer";
4659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kRuntime:
4660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "runtime";
4661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kSamplingProfiler:
4662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "sampling profiler";
4663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kSnapshotCreator:
4664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "snapshot creator";
4665f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kTesting:
4666f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "testing";
4667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case GarbageCollectionReason::kUnknown:
4668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "unknown";
4669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
4670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  UNREACHABLE();
4671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return "";
4672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
4673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
4674109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool Heap::Contains(HeapObject* value) {
4675bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (memory_allocator()->IsOutsideAllocatedSpace(value->address())) {
4676109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return false;
4677109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
46788389745919cae02139ddc085a63c00d024269cf2Ben Murdoch  return HasBeenSetUp() &&
4679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         (new_space_->ToSpaceContains(value) || old_space_->Contains(value) ||
4680109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          code_space_->Contains(value) || map_space_->Contains(value) ||
4681109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          lo_space_->Contains(value));
46828389745919cae02139ddc085a63c00d024269cf2Ben Murdoch}
4683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4684109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool Heap::ContainsSlow(Address addr) {
4685bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (memory_allocator()->IsOutsideAllocatedSpace(addr)) {
4686109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return false;
4687109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4688109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return HasBeenSetUp() &&
4689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         (new_space_->ToSpaceContainsSlow(addr) ||
4690109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          old_space_->ContainsSlow(addr) || code_space_->ContainsSlow(addr) ||
4691109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          map_space_->ContainsSlow(addr) || lo_space_->ContainsSlow(addr));
4692109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
4693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4694f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochbool Heap::InSpace(HeapObject* value, AllocationSpace space) {
4695bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (memory_allocator()->IsOutsideAllocatedSpace(value->address())) {
4696109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return false;
4697109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4698109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!HasBeenSetUp()) return false;
4699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4700109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  switch (space) {
4701109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case NEW_SPACE:
4702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return new_space_->ToSpaceContains(value);
4703109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case OLD_SPACE:
4704109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return old_space_->Contains(value);
4705109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case CODE_SPACE:
4706109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return code_space_->Contains(value);
4707109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MAP_SPACE:
4708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return map_space_->Contains(value);
4709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case LO_SPACE:
4710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return lo_space_->Contains(value);
4711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4712109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  UNREACHABLE();
4713109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return false;
4714109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
4715f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
4716109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool Heap::InSpaceSlow(Address addr, AllocationSpace space) {
4717bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (memory_allocator()->IsOutsideAllocatedSpace(addr)) {
4718109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return false;
4719109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return false;
4721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (space) {
4723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NEW_SPACE:
4724f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return new_space_->ToSpaceContainsSlow(addr);
4725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
4726109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return old_space_->ContainsSlow(addr);
4727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_SPACE:
4728109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return code_space_->ContainsSlow(addr);
4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case MAP_SPACE:
4730109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return map_space_->ContainsSlow(addr);
4731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LO_SPACE:
4732109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return lo_space_->ContainsSlow(addr);
4733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
4735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
4736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::IsValidAllocationSpace(AllocationSpace space) {
4740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (space) {
4741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case NEW_SPACE:
4742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
4743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CODE_SPACE:
4744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MAP_SPACE:
4745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case LO_SPACE:
4746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
4747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
4748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
4749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Heap::RootIsImmortalImmovable(int root_index) {
4754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  switch (root_index) {
4755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define IMMORTAL_IMMOVABLE_ROOT(name) case Heap::k##name##RootIndex:
4756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
4757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef IMMORTAL_IMMOVABLE_ROOT
4758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define INTERNALIZED_STRING(name, value) case Heap::k##name##RootIndex:
4759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    INTERNALIZED_STRING_LIST(INTERNALIZED_STRING)
4760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef INTERNALIZED_STRING
4761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define STRING_TYPE(NAME, size, name, Name) case Heap::k##Name##MapRootIndex:
4762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    STRING_TYPE_LIST(STRING_TYPE)
4763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef STRING_TYPE
4764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return true;
4765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    default:
4766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return false;
4767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
4768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
4769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
4772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::Verify() {
4773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(HasBeenSetUp());
4774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate());
4775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
477662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // We have to wait here for the sweeper threads to have an iterable heap.
477762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  mark_compact_collector()->EnsureSweepingCompleted();
4778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VerifyPointersVisitor visitor;
4780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateRoots(&visitor, VISIT_ONLY_STRONG);
4781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VerifySmisVisitor smis_visitor;
4783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateSmiRoots(&smis_visitor);
4784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4785f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_space_->Verify();
4786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  old_space_->Verify(&visitor);
4788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map_space_->Verify(&visitor);
4789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VerifyPointersVisitor no_dirty_regions_visitor;
4791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_space_->Verify(&no_dirty_regions_visitor);
4792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  lo_space_->Verify();
4794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mark_compact_collector()->VerifyWeakEmbeddedObjectsInCode();
4796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_omit_map_checks_for_leaf_maps) {
4797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    mark_compact_collector()->VerifyOmittedMapChecks();
4798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
4801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ZapFromSpace() {
4804f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!new_space_->IsFromSpaceCommitted()) return;
480562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for (Page* page :
480662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       PageRange(new_space_->FromSpaceStart(), new_space_->FromSpaceEnd())) {
4807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Address cursor = page->area_start(), limit = page->area_end();
4808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         cursor < limit; cursor += kPointerSize) {
4809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Memory::Address_at(cursor) = kFromSpaceZapValue;
4810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4814c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor {
4815c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch public:
4816c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  IterateAndScavengePromotedObjectsVisitor(Heap* heap, HeapObject* target,
4817c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                           bool record_slots)
4818c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      : heap_(heap), target_(target), record_slots_(record_slots) {}
4819c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
4820c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  inline void VisitPointers(Object** start, Object** end) override {
4821c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Address slot_address = reinterpret_cast<Address>(start);
4822c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Page* page = Page::FromAddress(slot_address);
4823c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
4824c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    while (slot_address < reinterpret_cast<Address>(end)) {
4825c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Object** slot = reinterpret_cast<Object**>(slot_address);
4826c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Object* target = *slot;
4827c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
4828c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (target->IsHeapObject()) {
4829c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (heap_->InFromSpace(target)) {
4830c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          Scavenger::ScavengeObject(reinterpret_cast<HeapObject**>(slot),
4831c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                    HeapObject::cast(target));
4832c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          target = *slot;
4833c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          if (heap_->InNewSpace(target)) {
4834c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            SLOW_DCHECK(heap_->InToSpace(target));
4835c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            SLOW_DCHECK(target->IsHeapObject());
4836c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            RememberedSet<OLD_TO_NEW>::Insert(page, slot_address);
4837c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          }
4838c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          SLOW_DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(
4839c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch              HeapObject::cast(target)));
4840c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        } else if (record_slots_ &&
4841c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                   MarkCompactCollector::IsOnEvacuationCandidate(
4842c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       HeapObject::cast(target))) {
4843c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          heap_->mark_compact_collector()->RecordSlot(target_, slot, target);
4844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
4845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4847c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      slot_address += kPointerSize;
4848c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
4849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4851c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  inline void VisitCodeEntry(Address code_entry_slot) override {
48523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Black allocation requires us to process objects referenced by
48533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // promoted objects.
48543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (heap_->incremental_marking()->black_allocation()) {
48553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot));
4856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      IncrementalMarking::MarkGrey(heap_, code);
48573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
48583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
4859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
4861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Heap* heap_;
4862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* target_;
4863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool record_slots_;
4864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
4865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4866c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid Heap::IterateAndScavengePromotedObject(HeapObject* target, int size,
4867c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                            bool was_marked_black) {
4868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We are not collecting slots on new space objects during mutation
4869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // thus we have to scan for pointers to evacuation candidates when we
4870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // promote objects. But we should not record any slots in non-black
4871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // objects. Grey object's slots would be rescanned.
4872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // White object might not survive until the end of collection
4873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it would be a violation of the invariant to record it's slots.
4874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool record_slots = false;
4875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incremental_marking()->IsCompacting()) {
487662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    record_slots = ObjectMarking::IsBlack(target);
4877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4879c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  IterateAndScavengePromotedObjectsVisitor visitor(this, target, record_slots);
4880c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (target->IsJSFunction()) {
4881c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // JSFunctions reachable through kNextFunctionLinkOffset are weak. Slots for
4882c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // this links are recorded during processing of weak lists.
4883c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    JSFunction::BodyDescriptorWeakCode::IterateBody(target, size, &visitor);
4884c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
4885c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    target->IterateBody(target->map()->instance_type(), size, &visitor);
4886c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
48873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
48883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // When black allocations is on, we have to visit not already marked black
48893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // objects (in new space) promoted to black pages to keep their references
48903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // alive.
48913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // TODO(hpayer): Implement a special promotion visitor that incorporates
48923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // regular visiting and IteratePromotedObjectPointers.
48933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!was_marked_black) {
48943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (incremental_marking()->black_allocation()) {
4895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      IncrementalMarking::MarkGrey(this, target->map());
48963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      incremental_marking()->IterateBlackObject(target);
48973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
48983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
4899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) {
4903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateStrongRoots(v, mode);
4904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateWeakRoots(v, mode);
4905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) {
4909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->VisitPointer(reinterpret_cast<Object**>(&roots_[kStringTableRootIndex]));
4910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kStringTable);
4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode != VISIT_ALL_IN_SCAVENGE && mode != VISIT_ALL_IN_SWEEP_NEWSPACE) {
4912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Scavenge collections have special processing for this.
491362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    external_string_table_.IterateAll(v);
4914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kExternalStringsTable);
4916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateSmiRoots(ObjectVisitor* v) {
4920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Acquire execution access since we are going to read stack limit values.
4921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExecutionAccess access(isolate());
4922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->VisitPointers(&roots_[kSmiRootsStart], &roots_[kRootListLength]);
4923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kSmiRootList);
4924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// We cannot avoid stale handles to left-trimmed objects, but can only make
4927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// sure all handles still needed are updated. Filter out a stale pointer
4928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// and clear the slot to allow post processing of handles (needed because
4929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// the sweeper might actually free the underlying page).
4930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass FixStaleLeftTrimmedHandlesVisitor : public ObjectVisitor {
4931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
4932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit FixStaleLeftTrimmedHandlesVisitor(Heap* heap) : heap_(heap) {
4933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    USE(heap_);
4934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
4935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
4936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void VisitPointer(Object** p) override { FixHandle(p); }
4937f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
4938f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void VisitPointers(Object** start, Object** end) override {
4939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (Object** p = start; p < end; p++) FixHandle(p);
4940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
4941f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
4942f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
4943f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  inline void FixHandle(Object** p) {
4944f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    HeapObject* current = reinterpret_cast<HeapObject*>(*p);
4945f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (!current->IsHeapObject()) return;
4946f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const MapWord map_word = current->map_word();
4947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (!map_word.IsForwardingAddress() && current->IsFiller()) {
4948f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#ifdef DEBUG
4949f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // We need to find a FixedArrayBase map after walking the fillers.
4950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      while (current->IsFiller()) {
4951f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Address next = reinterpret_cast<Address>(current);
4952f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (current->map() == heap_->one_pointer_filler_map()) {
4953f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          next += kPointerSize;
4954f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        } else if (current->map() == heap_->two_pointer_filler_map()) {
4955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          next += 2 * kPointerSize;
4956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        } else {
4957f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          next += current->Size();
4958f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
4959f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        current = reinterpret_cast<HeapObject*>(next);
4960f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
4961f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DCHECK(current->IsFixedArrayBase());
4962f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#endif  // DEBUG
4963f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      *p = nullptr;
4964f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
4965f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
4966f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
4967f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Heap* heap_;
4968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
4969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
4971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
4972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kStrongRootList);
49733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The serializer/deserializer iterates the root list twice, first to pick
49743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // off immortal immovable roots to make sure they end up on the first page,
49753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // and then again for the rest.
49763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (mode == VISIT_ONLY_STRONG_ROOT_LIST) return;
4977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->bootstrapper()->Iterate(v);
4979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kBootstrapper);
4980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->Iterate(v);
4981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kTop);
4982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Relocatable::Iterate(isolate_, v);
4983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kRelocatable);
498413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  isolate_->debug()->Iterate(v);
498513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  v->Synchronize(VisitorSynchronization::kDebug);
4986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->compilation_cache()->Iterate(v);
4988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kCompilationCache);
4989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over local handles in handle scopes.
4991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FixStaleLeftTrimmedHandlesVisitor left_trim_visitor(this);
4992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  isolate_->handle_scope_implementer()->Iterate(&left_trim_visitor);
4993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->handle_scope_implementer()->Iterate(v);
4994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->IterateDeferredHandles(v);
4995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kHandleScope);
4996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over the builtin code objects and code stubs in the
4998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // heap. Note that it is not necessary to iterate over code objects
4999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // on scavenge collections.
5000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode != VISIT_ALL_IN_SCAVENGE) {
5001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->builtins()->IterateBuiltins(v);
5002109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    v->Synchronize(VisitorSynchronization::kBuiltins);
5003109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    isolate_->interpreter()->IterateDispatchTable(v);
5004109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    v->Synchronize(VisitorSynchronization::kDispatchTable);
5005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over global handles.
5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (mode) {
50093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case VISIT_ONLY_STRONG_ROOT_LIST:
50103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      UNREACHABLE();
50113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
50123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case VISIT_ONLY_STRONG_FOR_SERIALIZATION:
501362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
501462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case VISIT_ONLY_STRONG:
5015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->global_handles()->IterateStrongRoots(v);
5016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VISIT_ALL_IN_SCAVENGE:
5018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v);
5019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VISIT_ALL_IN_SWEEP_NEWSPACE:
5021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VISIT_ALL:
5022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->global_handles()->IterateAllRoots(v);
5023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kGlobalHandles);
5026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over eternal handles.
5028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == VISIT_ALL_IN_SCAVENGE) {
5029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->eternal_handles()->IterateNewSpaceRoots(v);
5030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
5031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->eternal_handles()->IterateAllRoots(v);
5032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kEternalHandles);
5034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over pointers being held by inactive threads.
5036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->thread_manager()->Iterate(v);
5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kThreadManager);
5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Iterate over other strong roots (currently only identity maps).
5040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (StrongRootsList* list = strong_roots_list_; list; list = list->next) {
5041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    v->VisitPointers(list->start, list->end);
5042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  v->Synchronize(VisitorSynchronization::kStrongRoots);
5044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
50453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Iterate over the partial snapshot cache unless serializing.
50463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (mode != VISIT_ONLY_STRONG_FOR_SERIALIZATION) {
50473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    SerializerDeserializer::Iterate(isolate_, v);
50483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
5049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We don't do a v->Synchronize call here, because in debug mode that will
5050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // output a flag to the snapshot.  However at this point the serializer and
5051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deserializer are deliberately a little unsynchronized (see above) so the
5052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // checking of the sync flag in the snapshot would fail.
5053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(1236194): Since the heap size is configurable on the command line
5057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and through the API, we should gracefully handle the case that the heap
5058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// size is not big enough to fit all the initial objects.
5059c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool Heap::ConfigureHeap(size_t max_semi_space_size, size_t max_old_space_size,
5060c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         size_t max_executable_size, size_t code_range_size) {
5061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HasBeenSetUp()) return false;
5062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Overwrite default configuration.
5064c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (max_semi_space_size != 0) {
5065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    max_semi_space_size_ = max_semi_space_size * MB;
5066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5067c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (max_old_space_size != 0) {
5068c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    max_old_generation_size_ = max_old_space_size * MB;
5069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5070c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (max_executable_size != 0) {
5071c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    max_executable_size_ = max_executable_size * MB;
5072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If max space size flags are specified overwrite the configuration.
5075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_max_semi_space_size > 0) {
5076c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    max_semi_space_size_ = static_cast<size_t>(FLAG_max_semi_space_size) * MB;
5077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_max_old_space_size > 0) {
5079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_old_generation_size_ =
5080c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        static_cast<size_t>(FLAG_max_old_space_size) * MB;
5081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_max_executable_size > 0) {
5083c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    max_executable_size_ = static_cast<size_t>(FLAG_max_executable_size) * MB;
5084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Page::kPageSize > MB) {
5087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_semi_space_size_ = ROUND_UP(max_semi_space_size_, Page::kPageSize);
5088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_old_generation_size_ =
5089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ROUND_UP(max_old_generation_size_, Page::kPageSize);
5090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_executable_size_ = ROUND_UP(max_executable_size_, Page::kPageSize);
5091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_stress_compaction) {
5094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This will cause more frequent GCs when stressing.
5095f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    max_semi_space_size_ = MB;
5096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The new space size must be a power of two to support single-bit testing
5099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for containment.
5100c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  max_semi_space_size_ = base::bits::RoundUpToPowerOfTwo32(
5101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      static_cast<uint32_t>(max_semi_space_size_));
5102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_min_semi_space_size > 0) {
5104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    size_t initial_semispace_size =
5105c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        static_cast<size_t>(FLAG_min_semi_space_size) * MB;
5106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (initial_semispace_size > max_semi_space_size_) {
5107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      initial_semispace_size_ = max_semi_space_size_;
5108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_trace_gc) {
5109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintIsolate(isolate_,
5110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "Min semi-space size cannot be more than the maximum "
5111c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                     "semi-space size of %" PRIuS " MB\n",
5112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     max_semi_space_size_ / MB);
5113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
5114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
5115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      initial_semispace_size_ =
5116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ROUND_UP(initial_semispace_size, Page::kPageSize);
5117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  initial_semispace_size_ = Min(initial_semispace_size_, max_semi_space_size_);
5121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_semi_space_growth_factor < 2) {
5123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    FLAG_semi_space_growth_factor = 2;
5124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The old generation is paged and needs at least one page for each space.
5127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
512862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  initial_max_old_generation_size_ = max_old_generation_size_ =
5129c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Max(static_cast<size_t>(paged_space_count * Page::kPageSize),
5130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          max_old_generation_size_);
5131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The max executable size must be less than or equal to the max old
5133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // generation size.
5134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (max_executable_size_ > max_old_generation_size_) {
5135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_executable_size_ = max_old_generation_size_;
5136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_initial_old_space_size > 0) {
5139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    initial_old_generation_size_ = FLAG_initial_old_space_size * MB;
5140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
5141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    initial_old_generation_size_ =
5142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        max_old_generation_size_ / kInitalOldGenerationLimitFactor;
5143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  old_generation_allocation_limit_ = initial_old_generation_size_;
5145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We rely on being able to allocate new arrays in paged spaces.
5147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(kMaxRegularHeapObjectSize >=
5148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (JSArray::kSize +
5149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          FixedArray::SizeFor(JSArray::kInitialMaxFastElementArray) +
5150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          AllocationMemento::kSize));
5151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_range_size_ = code_range_size * MB;
5153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  configured_ = true;
5155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
5156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddToRingBuffer(const char* string) {
5160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t first_part =
5161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Min(strlen(string), kTraceRingBufferSize - ring_buffer_end_);
5162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  memcpy(trace_ring_buffer_ + ring_buffer_end_, string, first_part);
5163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ring_buffer_end_ += first_part;
5164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (first_part < strlen(string)) {
5165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ring_buffer_full_ = true;
5166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t second_part = strlen(string) - first_part;
5167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    memcpy(trace_ring_buffer_, string + first_part, second_part);
5168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ring_buffer_end_ = second_part;
5169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::GetFromRingBuffer(char* buffer) {
5174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t copied = 0;
5175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (ring_buffer_full_) {
5176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    copied = kTraceRingBufferSize - ring_buffer_end_;
5177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    memcpy(buffer, trace_ring_buffer_ + ring_buffer_end_, copied);
5178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  memcpy(buffer + copied, trace_ring_buffer_, ring_buffer_end_);
5180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::ConfigureHeapDefault() { return ConfigureHeap(0, 0, 0, 0); }
5184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
5187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->start_marker = HeapStats::kStartMarker;
5188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->end_marker = HeapStats::kEndMarker;
5189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  *stats->new_space_size = new_space_->Size();
5190f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  *stats->new_space_capacity = new_space_->Capacity();
5191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *stats->old_space_size = old_space_->SizeOfObjects();
5192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *stats->old_space_capacity = old_space_->Capacity();
5193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->code_space_size = code_space_->SizeOfObjects();
5194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->code_space_capacity = code_space_->Capacity();
5195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->map_space_size = map_space_->SizeOfObjects();
5196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->map_space_capacity = map_space_->Capacity();
5197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->lo_space_size = lo_space_->Size();
5198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->global_handles()->RecordStats(stats);
5199bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  *stats->memory_allocator_size = memory_allocator()->Size();
5200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->memory_allocator_capacity =
5201bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      memory_allocator()->Size() + memory_allocator()->Available();
5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->os_error = base::OS::GetLastError();
5203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  *stats->malloced_memory = isolate_->allocator()->GetCurrentMemoryUsage();
5204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  *stats->malloced_peak_memory = isolate_->allocator()->GetMaxMemoryUsage();
5205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (take_snapshot) {
5206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HeapIterator iterator(this);
5207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (HeapObject* obj = iterator.next(); obj != NULL;
5208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         obj = iterator.next()) {
5209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      InstanceType type = obj->map()->instance_type();
5210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(0 <= type && type <= LAST_TYPE);
5211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stats->objects_per_type[type]++;
5212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stats->size_per_type[type] += obj->Size();
5213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (stats->last_few_messages != NULL)
5216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GetFromRingBuffer(stats->last_few_messages);
5217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (stats->js_stacktrace != NULL) {
5218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedStringAllocator fixed(stats->js_stacktrace, kStacktraceBufferSize - 1);
5219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StringStream accumulator(&fixed, StringStream::kPrintObjectConcise);
5220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (gc_state() == Heap::NOT_IN_GC) {
5221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->PrintStack(&accumulator, Isolate::kPrintStackVerbose);
5222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
5223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      accumulator.Add("Cannot get stack trace in GC.");
5224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5228c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochsize_t Heap::PromotedSpaceSizeOfObjects() {
5229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return old_space_->SizeOfObjects() + code_space_->SizeOfObjects() +
5230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         map_space_->SizeOfObjects() + lo_space_->SizeOfObjects();
5231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5233c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochuint64_t Heap::PromotedExternalMemorySize() {
523413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (external_memory_ <= external_memory_at_last_mark_compact_) return 0;
5235c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return static_cast<uint64_t>(external_memory_ -
5236c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                               external_memory_at_last_mark_compact_);
5237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kMinHeapGrowingFactor = 1.1;
5241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kMaxHeapGrowingFactor = 4.0;
5242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kMaxHeapGrowingFactorMemoryConstrained = 2.0;
5243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kMaxHeapGrowingFactorIdle = 1.5;
5244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double Heap::kConservativeHeapGrowingFactor = 1.3;
5245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kTargetMutatorUtilization = 0.97;
5246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Given GC speed in bytes per ms, the allocation throughput in bytes per ms
5248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// (mutator speed), this function returns the heap growing factor that will
5249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// achieve the kTargetMutatorUtilisation if the GC speed and the mutator speed
5250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// remain the same until the next GC.
5251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// For a fixed time-frame T = TM + TG, the mutator utilization is the ratio
5253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TM / (TM + TG), where TM is the time spent in the mutator and TG is the
5254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// time spent in the garbage collector.
5255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Let MU be kTargetMutatorUtilisation, the desired mutator utilization for the
5257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// time-frame from the end of the current GC to the end of the next GC. Based
5258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// on the MU we can compute the heap growing factor F as
5259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// F = R * (1 - MU) / (R * (1 - MU) - MU), where R = gc_speed / mutator_speed.
5261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// This formula can be derived as follows.
5263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// F = Limit / Live by definition, where the Limit is the allocation limit,
5265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// and the Live is size of live objects.
5266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Let’s assume that we already know the Limit. Then:
5267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TG = Limit / gc_speed
5268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TM = (TM + TG) * MU, by definition of MU.
5269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TM = TG * MU / (1 - MU)
5270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TM = Limit *  MU / (gc_speed * (1 - MU))
5271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// On the other hand, if the allocation throughput remains constant:
5272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   Limit = Live + TM * allocation_throughput = Live + TM * mutator_speed
5273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Solving it for TM, we get
5274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TM = (Limit - Live) / mutator_speed
5275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Combining the two equation for TM:
5276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   (Limit - Live) / mutator_speed = Limit * MU / (gc_speed * (1 - MU))
5277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   (Limit - Live) = Limit * MU * mutator_speed / (gc_speed * (1 - MU))
5278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// substitute R = gc_speed / mutator_speed
5279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   (Limit - Live) = Limit * MU  / (R * (1 - MU))
5280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// substitute F = Limit / Live
5281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F - 1 = F * MU  / (R * (1 - MU))
5282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F - F * MU / (R * (1 - MU)) = 1
5283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F * (1 - MU / (R * (1 - MU))) = 1
5284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F * (R * (1 - MU) - MU) / (R * (1 - MU)) = 1
5285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F = R * (1 - MU) / (R * (1 - MU) - MU)
5286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble Heap::HeapGrowingFactor(double gc_speed, double mutator_speed) {
5287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (gc_speed == 0 || mutator_speed == 0) return kMaxHeapGrowingFactor;
5288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double speed_ratio = gc_speed / mutator_speed;
5290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double mu = kTargetMutatorUtilization;
5291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double a = speed_ratio * (1 - mu);
5293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double b = speed_ratio * (1 - mu) - mu;
5294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The factor is a / b, but we need to check for small b first.
5296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double factor =
5297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      (a < b * kMaxHeapGrowingFactor) ? a / b : kMaxHeapGrowingFactor;
5298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  factor = Min(factor, kMaxHeapGrowingFactor);
5299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  factor = Max(factor, kMinHeapGrowingFactor);
5300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return factor;
5301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5303c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochsize_t Heap::CalculateOldGenerationAllocationLimit(double factor,
5304c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                                   size_t old_gen_size) {
5305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(factor > 1.0);
5306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(old_gen_size > 0);
5307c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  uint64_t limit = static_cast<uint64_t>(old_gen_size * factor);
5308c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  limit = Max(limit, static_cast<uint64_t>(old_gen_size) +
5309c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         MinimumAllocationLimitGrowingStep());
5310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  limit += new_space_->Capacity();
5311c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  uint64_t halfway_to_the_max =
5312c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      (static_cast<uint64_t>(old_gen_size) + max_old_generation_size_) / 2;
5313c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return static_cast<size_t>(Min(limit, halfway_to_the_max));
5314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5316c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochsize_t Heap::MinimumAllocationLimitGrowingStep() {
5317c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const size_t kRegularAllocationLimitGrowingStep = 8;
5318c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const size_t kLowMemoryAllocationLimitGrowingStep = 2;
5319c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t limit = (Page::kPageSize > MB ? Page::kPageSize : MB);
5320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return limit * (ShouldOptimizeForMemoryUsage()
5321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      ? kLowMemoryAllocationLimitGrowingStep
5322f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      : kRegularAllocationLimitGrowingStep);
5323f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5325c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid Heap::SetOldGenerationAllocationLimit(size_t old_gen_size, double gc_speed,
5326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           double mutator_speed) {
5327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double factor = HeapGrowingFactor(gc_speed, mutator_speed);
5328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_gc_verbose) {
5330f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    isolate_->PrintWithTimestamp(
5331f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f "
5332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        "(gc=%.f, mutator=%.f)\n",
5333f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        factor, kTargetMutatorUtilization, gc_speed / mutator_speed, gc_speed,
5334f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        mutator_speed);
5335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (IsMemoryConstrainedDevice()) {
5338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained);
5339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (memory_reducer_->ShouldGrowHeapSlowly() ||
5342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ShouldOptimizeForMemoryUsage()) {
5343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    factor = Min(factor, kConservativeHeapGrowingFactor);
5344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_stress_compaction || ShouldReduceMemory()) {
5347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    factor = kMinHeapGrowingFactor;
5348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_heap_growing_percent > 0) {
5351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    factor = 1.0 + FLAG_heap_growing_percent / 100.0;
5352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  old_generation_allocation_limit_ =
5355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_gc_verbose) {
5358c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    isolate_->PrintWithTimestamp(
5359c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        "Grow: old size: %" PRIuS " KB, new limit: %" PRIuS " KB (%.1f)\n",
5360c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        old_gen_size / KB, old_generation_allocation_limit_ / KB, factor);
5361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid Heap::DampenOldGenerationAllocationLimit(size_t old_gen_size,
5365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              double gc_speed,
5366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              double mutator_speed) {
5367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double factor = HeapGrowingFactor(gc_speed, mutator_speed);
5368c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (limit < old_generation_allocation_limit_) {
5370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FLAG_trace_gc_verbose) {
5371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      isolate_->PrintWithTimestamp(
5372c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          "Dampen: old size: %" PRIuS " KB, old limit: %" PRIuS
5373f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          " KB, "
5374c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          "new limit: %" PRIuS " KB (%.1f)\n",
5375f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          old_gen_size / KB, old_generation_allocation_limit_ / KB, limit / KB,
5376f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          factor);
5377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    old_generation_allocation_limit_ = limit;
5379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
538262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool Heap::ShouldOptimizeForLoadTime() {
538362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return isolate()->rail_mode() == PERFORMANCE_LOAD &&
538462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch         !AllocationLimitOvershotByLargeMargin() &&
538562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch         MonotonicallyIncreasingTimeInMs() <
538662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             isolate()->LoadStartTimeMs() + kMaxLoadTimeMs;
538762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
538862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5389f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// This predicate is called when an old generation space cannot allocated from
5390f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// the free list and is about to add a new page. Returning false will cause a
5391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// major GC. It happens when the old generation allocation limit is reached and
5392f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// - either we need to optimize for memory usage,
5393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// - or the incremental marking is not in progress and we cannot start it.
5394c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool Heap::ShouldExpandOldGenerationOnSlowAllocation() {
5395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (always_allocate() || OldGenerationSpaceAvailable() > 0) return true;
5396f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // We reached the old generation allocation limit.
5397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5398f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (ShouldOptimizeForMemoryUsage()) return false;
5399f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
540062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (ShouldOptimizeForLoadTime()) return true;
540162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5402c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (incremental_marking()->NeedsFinalization()) {
5403c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return !AllocationLimitOvershotByLargeMargin();
5404c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
5405c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
5406f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (incremental_marking()->IsStopped() &&
5407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      IncrementalMarkingLimitReached() == IncrementalMarkingLimit::kNoLimit) {
5408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // We cannot start incremental marking.
5409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return false;
5410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return true;
5412f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5414f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// This function returns either kNoLimit, kSoftLimit, or kHardLimit.
5415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// The kNoLimit means that either incremental marking is disabled or it is too
5416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// early to start incremental marking.
5417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// The kSoftLimit means that incremental marking should be started soon.
5418f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// The kHardLimit means that incremental marking should be started immediately.
5419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHeap::IncrementalMarkingLimit Heap::IncrementalMarkingLimitReached() {
5420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!incremental_marking()->CanBeActivated() ||
5421c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      PromotedSpaceSizeOfObjects() <=
5422c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          IncrementalMarking::kActivationThreshold) {
5423f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Incremental marking is disabled or it is too early to start.
5424f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return IncrementalMarkingLimit::kNoLimit;
5425f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5426f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if ((FLAG_stress_compaction && (gc_count_ & 1) != 0) ||
5427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      HighMemoryPressure()) {
5428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // If there is high memory pressure or stress testing is enabled, then
5429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // start marking immediately.
5430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return IncrementalMarkingLimit::kHardLimit;
5431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5432c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t old_generation_space_available = OldGenerationSpaceAvailable();
5433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (old_generation_space_available > new_space_->Capacity()) {
5434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return IncrementalMarkingLimit::kNoLimit;
5435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
543662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (ShouldOptimizeForMemoryUsage()) {
543762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return IncrementalMarkingLimit::kHardLimit;
543862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
543962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (ShouldOptimizeForLoadTime()) {
544062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return IncrementalMarkingLimit::kNoLimit;
544162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
544262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (old_generation_space_available == 0) {
5443f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return IncrementalMarkingLimit::kHardLimit;
5444f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5445f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IncrementalMarkingLimit::kSoftLimit;
5446f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnableInlineAllocation() {
5449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!inline_allocation_disabled_) return;
5450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline_allocation_disabled_ = false;
5451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update inline allocation limit for new space.
5453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space()->UpdateInlineAllocationLimit(0);
5454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::DisableInlineAllocation() {
5458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (inline_allocation_disabled_) return;
5459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline_allocation_disabled_ = true;
5460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update inline allocation limit for new space.
5462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space()->UpdateInlineAllocationLimit(0);
5463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update inline allocation limit for old spaces.
5465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PagedSpaces spaces(this);
5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (PagedSpace* space = spaces.next(); space != NULL;
5467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       space = spaces.next()) {
5468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    space->EmptyAllocationInfo();
5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochV8_DECLARE_ONCE(initialize_gc_once);
5474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void InitializeGCOnce() {
5476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scavenger::Initialize();
5477c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  StaticScavengeVisitor::Initialize();
5478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MarkCompactCollector::Initialize();
5479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::SetUp() {
5483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
5484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  allocation_timeout_ = FLAG_gc_interval;
5485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
5486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize heap spaces and initial maps and objects. Whenever something
5488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // goes wrong, just return false. The caller should check the results and
5489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // call Heap::TearDown() to release allocated memory.
5490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
5491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the heap is not yet configured (e.g. through the API), configure it.
5492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Configuration is based on the flags new-space-size (really the semispace
5493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // size) and old-space-size if set or the initial values of semispace_size_
5494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and old_generation_size_ otherwise.
5495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!configured_) {
5496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!ConfigureHeapDefault()) return false;
5497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::CallOnce(&initialize_gc_once, &InitializeGCOnce);
5500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up memory allocator.
5502bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  memory_allocator_ = new MemoryAllocator(isolate_);
5503bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (!memory_allocator_->SetUp(MaxReserved(), MaxExecutableSize(),
5504bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                code_range_size_))
5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
5506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Initialize store buffer.
5508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  store_buffer_ = new StoreBuffer(this);
5509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
5510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Initialize incremental marking.
5511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incremental_marking_ = new IncrementalMarking(this);
5512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5513f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (int i = 0; i <= LAST_SPACE; i++) {
5514f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    space_[i] = nullptr;
5515f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5516f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  space_[NEW_SPACE] = new_space_ = new NewSpace(this);
5518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!new_space_->SetUp(initial_semispace_size_, max_semi_space_size_)) {
5519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
5520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_top_after_last_gc_ = new_space()->top();
5522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  space_[OLD_SPACE] = old_space_ =
5524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      new OldSpace(this, OLD_SPACE, NOT_EXECUTABLE);
5525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!old_space_->SetUp()) return false;
5526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  space_[CODE_SPACE] = code_space_ = new OldSpace(this, CODE_SPACE, EXECUTABLE);
5528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!code_space_->SetUp()) return false;
5529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5530f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  space_[MAP_SPACE] = map_space_ = new MapSpace(this, MAP_SPACE);
5531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!map_space_->SetUp()) return false;
5532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The large object code space may contain code or data.  We set the memory
5534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to be non-executable here for safety, but this means we need to enable it
5535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // explicitly when allocating large code objects.
5536f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  space_[LO_SPACE] = lo_space_ = new LargeObjectSpace(this, LO_SPACE);
5537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!lo_space_->SetUp()) return false;
5538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up the seed that is used to randomize the string hash function.
5540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(hash_seed() == 0);
5541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_randomize_hashes) {
5542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_hash_seed == 0) {
5543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int rnd = isolate()->random_number_generator()->NextInt();
5544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_hash_seed(Smi::FromInt(rnd & Name::kHashBitMask));
5545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
5546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_hash_seed(Smi::FromInt(FLAG_hash_seed));
5547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount);
5551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       i++) {
5552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    deferred_counters_[i] = 0;
5553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer_ = new GCTracer(this);
5556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_collector_ = new Scavenger(this);
5557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mark_compact_collector_ = new MarkCompactCollector(this);
5558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  gc_idle_time_handler_ = new GCIdleTimeHandler();
5559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  memory_reducer_ = new MemoryReducer(this);
5560c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (V8_UNLIKELY(FLAG_gc_stats)) {
5561f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    live_object_stats_ = new ObjectStats(this);
5562f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    dead_object_stats_ = new ObjectStats(this);
5563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
5564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_job_ = new ScavengeJob();
556562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  local_embedder_heap_tracer_ = new LocalEmbedderHeapTracer();
5566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
5568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, IntPtrTEvent("heap-available", Available()));
5569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_buffer()->SetUp();
5571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  mark_compact_collector()->SetUp();
5573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  idle_scavenge_observer_ = new IdleScavengeObserver(
5575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *this, ScavengeJob::kBytesAllocatedBeforeNextIdleTask);
5576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  new_space()->AddAllocationObserver(idle_scavenge_observer_);
5577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
5579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CreateHeapObjects() {
5583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create initial maps.
5584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!CreateInitialMaps()) return false;
558562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!CreateApiObjects()) return false;
5586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create initial objects
5588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CreateInitialObjects();
5589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, gc_count_);
5590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_native_contexts_list(undefined_value());
5592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_allocation_sites_list(undefined_value());
5593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
5595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::SetStackLimits() {
5599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate_ != NULL);
5600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate_ == isolate());
5601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // On 64 bit machines, pointers are generally out of range of Smis.  We write
5602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // something that looks like an out of range Smi to the GC.
5603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up the special root array entries containing the stack limits.
5605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // These are actually addresses, but the tag makes the GC ignore it.
5606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  roots_[kStackLimitRootIndex] = reinterpret_cast<Object*>(
5607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag);
5608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  roots_[kRealStackLimitRootIndex] = reinterpret_cast<Object*>(
5609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag);
5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::ClearStackLimits() {
5613c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  roots_[kStackLimitRootIndex] = Smi::kZero;
5614c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  roots_[kRealStackLimitRootIndex] = Smi::kZero;
56153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
5616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::PrintAlloctionsHash() {
5618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t hash = StringHasher::GetHashCore(raw_allocations_hash_);
5619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintF("\n### Allocations = %u, hash = 0x%08x\n", allocations_count(), hash);
5620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::NotifyDeserializationComplete() {
5624f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_EQ(0, gc_count());
5625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PagedSpaces spaces(this);
5626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (PagedSpace* s = spaces.next(); s != NULL; s = spaces.next()) {
5627f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (isolate()->snapshot_available()) s->ShrinkImmortalImmovablePages();
5628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#ifdef DEBUG
5629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // All pages right after bootstrapping must be marked as never-evacuate.
563013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    for (Page* p : *s) {
563113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      CHECK(p->NeverEvacuate());
563213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
5633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // DEBUG
5634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5636f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  deserialization_complete_ = true;
5637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5639bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
5640c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(gc_state_, HeapState::NOT_IN_GC);
564162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  local_embedder_heap_tracer()->SetRemoteTracer(tracer);
5642bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
5643bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5644bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid Heap::TracePossibleWrapper(JSObject* js_object) {
5645f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(js_object->WasConstructedFromApiFunction());
5646f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (js_object->GetInternalFieldCount() >= 2 &&
5647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      js_object->GetInternalField(0) &&
5648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      js_object->GetInternalField(0) != undefined_value() &&
5649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      js_object->GetInternalField(1) != undefined_value()) {
5650f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(reinterpret_cast<intptr_t>(js_object->GetInternalField(0)) % 2 == 0);
565162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    local_embedder_heap_tracer()->AddWrapperToTrace(std::pair<void*, void*>(
5652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        reinterpret_cast<void*>(js_object->GetInternalField(0)),
5653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        reinterpret_cast<void*>(js_object->GetInternalField(1))));
5654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
5655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
5656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
56573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::RegisterExternallyReferencedObject(Object** object) {
5658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HeapObject* heap_object = HeapObject::cast(*object);
5659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(Contains(heap_object));
5660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (FLAG_incremental_marking_wrappers && incremental_marking()->IsMarking()) {
5661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    IncrementalMarking::MarkGrey(this, heap_object);
5662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
5663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(mark_compact_collector()->in_use());
566462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    mark_compact_collector()->MarkObject(heap_object);
5665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
56663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
5667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TearDown() {
5669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
5670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
5671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Verify();
5672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
5674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateMaximumCommitted();
5676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_predictable) {
5678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintAlloctionsHash();
5679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5681109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  new_space()->RemoveAllocationObserver(idle_scavenge_observer_);
5682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete idle_scavenge_observer_;
5683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  idle_scavenge_observer_ = nullptr;
5684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete scavenge_collector_;
5686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_collector_ = nullptr;
5687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mark_compact_collector_ != nullptr) {
5689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    mark_compact_collector_->TearDown();
5690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete mark_compact_collector_;
5691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    mark_compact_collector_ = nullptr;
5692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete incremental_marking_;
5695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incremental_marking_ = nullptr;
5696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete gc_idle_time_handler_;
5698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  gc_idle_time_handler_ = nullptr;
5699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (memory_reducer_ != nullptr) {
5701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    memory_reducer_->TearDown();
5702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete memory_reducer_;
5703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    memory_reducer_ = nullptr;
5704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (live_object_stats_ != nullptr) {
5707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    delete live_object_stats_;
5708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    live_object_stats_ = nullptr;
5709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
5710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
5711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (dead_object_stats_ != nullptr) {
5712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    delete dead_object_stats_;
5713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    dead_object_stats_ = nullptr;
5714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
5715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
571662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  delete local_embedder_heap_tracer_;
571762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  local_embedder_heap_tracer_ = nullptr;
571862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete scavenge_job_;
5720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_job_ = nullptr;
5721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->global_handles()->TearDown();
5723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  external_string_table_.TearDown();
5725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete tracer_;
5727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer_ = nullptr;
5728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5729f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_space_->TearDown();
5730f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  delete new_space_;
5731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_space_ = nullptr;
5732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (old_space_ != NULL) {
5734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete old_space_;
5735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    old_space_ = NULL;
5736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (code_space_ != NULL) {
5739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete code_space_;
5740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code_space_ = NULL;
5741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (map_space_ != NULL) {
5744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete map_space_;
5745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    map_space_ = NULL;
5746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lo_space_ != NULL) {
5749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    lo_space_->TearDown();
5750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete lo_space_;
5751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    lo_space_ = NULL;
5752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_buffer()->TearDown();
5755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5756bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  memory_allocator()->TearDown();
5757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* next = NULL;
5759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (StrongRootsList* list = strong_roots_list_; list; list = next) {
5760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next = list->next;
5761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete list;
5762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  strong_roots_list_ = NULL;
5764bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  delete store_buffer_;
5766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  store_buffer_ = nullptr;
5767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
5768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  delete memory_allocator_;
5769bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  memory_allocator_ = nullptr;
5770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddGCPrologueCallback(v8::Isolate::GCCallback callback,
5774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 GCType gc_type, bool pass_isolate) {
5775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callback != NULL);
5776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCCallbackPair pair(callback, gc_type, pass_isolate);
5777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!gc_prologue_callbacks_.Contains(pair));
5778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return gc_prologue_callbacks_.Add(pair);
5779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RemoveGCPrologueCallback(v8::Isolate::GCCallback callback) {
5783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callback != NULL);
5784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
5785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (gc_prologue_callbacks_[i].callback == callback) {
5786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_prologue_callbacks_.Remove(i);
5787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
5788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
5791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddGCEpilogueCallback(v8::Isolate::GCCallback callback,
5795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 GCType gc_type, bool pass_isolate) {
5796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callback != NULL);
5797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCCallbackPair pair(callback, gc_type, pass_isolate);
5798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!gc_epilogue_callbacks_.Contains(pair));
5799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return gc_epilogue_callbacks_.Add(pair);
5800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RemoveGCEpilogueCallback(v8::Isolate::GCCallback callback) {
5804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callback != NULL);
5805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
5806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (gc_epilogue_callbacks_[i].callback == callback) {
5807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_epilogue_callbacks_.Remove(i);
5808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
5809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
5812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(ishell): Find a better place for this.
5815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid Heap::AddWeakNewSpaceObjectToCodeDependency(Handle<HeapObject> obj,
5816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                 Handle<WeakCell> code) {
5817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(InNewSpace(*obj));
5818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(!InNewSpace(*code));
5819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<ArrayList> list(weak_new_space_object_to_code_list(), isolate());
5820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  list = ArrayList::Add(list, isolate()->factory()->NewWeakCell(obj), code);
5821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (*list != weak_new_space_object_to_code_list()) {
5822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    set_weak_new_space_object_to_code_list(*list);
5823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
5824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
5825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
5826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// TODO(ishell): Find a better place for this.
5827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj,
5828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Handle<DependentCode> dep) {
5829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(*obj));
5830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(*dep));
5831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<WeakHashTable> table(weak_object_to_code_table(), isolate());
5832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  table = WeakHashTable::Put(table, obj, dep);
5833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (*table != weak_object_to_code_table())
5834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_weak_object_to_code_table(*table);
5835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj));
5836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDependentCode* Heap::LookupWeakObjectToCodeDependency(Handle<HeapObject> obj) {
5840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* dep = weak_object_to_code_table()->Lookup(obj);
5841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dep->IsDependentCode()) return DependentCode::cast(dep);
5842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DependentCode::cast(empty_fixed_array());
5843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
584513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochnamespace {
584613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid CompactWeakFixedArray(Object* object) {
584713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (object->IsWeakFixedArray()) {
584813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    WeakFixedArray* array = WeakFixedArray::cast(object);
584913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    array->Compact<WeakFixedArray::NullCallback>();
585013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
585113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
585213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}  // anonymous namespace
585313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
585413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Heap::CompactWeakFixedArrays() {
585513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Find known WeakFixedArrays and compact them.
585613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  HeapIterator iterator(this);
585713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for (HeapObject* o = iterator.next(); o != NULL; o = iterator.next()) {
585813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (o->IsPrototypeInfo()) {
585913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Object* prototype_users = PrototypeInfo::cast(o)->prototype_users();
586013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (prototype_users->IsWeakFixedArray()) {
586113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        WeakFixedArray* array = WeakFixedArray::cast(prototype_users);
586213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        array->Compact<JSObject::PrototypeRegistryCompactionCallback>();
586313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
586413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
586513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
586613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  CompactWeakFixedArray(noscript_shared_function_infos());
586713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  CompactWeakFixedArray(script_list());
586813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  CompactWeakFixedArray(weak_stack_trace_list());
586913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
5870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddRetainedMap(Handle<Map> map) {
5872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<WeakCell> cell = Map::WeakCellForMap(map);
5873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<ArrayList> array(retained_maps(), isolate());
5874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (array->IsFull()) {
5875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CompactRetainedMaps(*array);
5876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array = ArrayList::Add(
5878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array, cell, handle(Smi::FromInt(FLAG_retain_maps_for_n_gc), isolate()),
5879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ArrayList::kReloadLengthAfterAllocation);
5880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (*array != retained_maps()) {
5881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_retained_maps(*array);
5882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::CompactRetainedMaps(ArrayList* retained_maps) {
5887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(retained_maps, this->retained_maps());
5888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length = retained_maps->Length();
5889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_length = 0;
5890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_number_of_disposed_maps = 0;
5891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This loop compacts the array by removing cleared weak cells.
5892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < length; i += 2) {
5893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(retained_maps->Get(i)->IsWeakCell());
5894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
5895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object* age = retained_maps->Get(i + 1);
5896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (cell->cleared()) continue;
5897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i != new_length) {
5898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      retained_maps->Set(new_length, cell);
5899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      retained_maps->Set(new_length + 1, age);
5900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i < number_of_disposed_maps_) {
5902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new_number_of_disposed_maps += 2;
5903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_length += 2;
5905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  number_of_disposed_maps_ = new_number_of_disposed_maps;
5907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* undefined = undefined_value();
5908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = new_length; i < length; i++) {
5909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    retained_maps->Clear(i, undefined);
5910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_length != length) retained_maps->SetLength(new_length);
5912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5914bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid Heap::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) {
5915bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  v8::internal::V8::FatalProcessOutOfMemory(location, is_heap_oom);
5916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
5919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PrintHandleVisitor : public ObjectVisitor {
5921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
5922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
5923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Object** p = start; p < end; p++)
5924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF("  handle %p to %p\n", reinterpret_cast<void*>(p),
5925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             reinterpret_cast<void*>(*p));
5926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::PrintHandles() {
5931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Handles:\n");
5932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintHandleVisitor v;
5933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->handle_scope_implementer()->Iterate(&v);
5934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
5937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CheckHandleCountVisitor : public ObjectVisitor {
5939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
5940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckHandleCountVisitor() : handle_count_(0) {}
5941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ~CheckHandleCountVisitor() override {
5942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(handle_count_ < HandleScope::kCheckHandleThreshold);
5943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
5945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    handle_count_ += end - start;
5946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
5949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ptrdiff_t handle_count_;
5950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
5951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::CheckHandleCount() {
5954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckHandleCountVisitor v;
5955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate_->handle_scope_implementer()->Iterate(&v);
5956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5958109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid Heap::ClearRecordedSlot(HeapObject* object, Object** slot) {
5959109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!InNewSpace(object)) {
5960109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Address slot_addr = reinterpret_cast<Address>(slot);
5961109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Page* page = Page::FromAddress(slot_addr);
5962109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
5963c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    store_buffer()->DeleteEntry(slot_addr);
59643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    RememberedSet<OLD_TO_OLD>::Remove(page, slot_addr);
5965109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
5966109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
5967109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
596862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool Heap::HasRecordedSlot(HeapObject* object, Object** slot) {
596962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (InNewSpace(object)) {
597062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return false;
597162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
597262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Address slot_addr = reinterpret_cast<Address>(slot);
597362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Page* page = Page::FromAddress(slot_addr);
597462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
597562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  store_buffer()->MoveAllEntriesToRememberedSet();
597662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return RememberedSet<OLD_TO_NEW>::Contains(page, slot_addr) ||
597762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch         RememberedSet<OLD_TO_OLD>::Contains(page, slot_addr);
597862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
597962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
59803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::ClearRecordedSlotRange(Address start, Address end) {
59813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Page* page = Page::FromAddress(start);
59823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!page->InNewSpace()) {
5983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
5984c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    store_buffer()->DeleteEntry(start, end);
5985c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    RememberedSet<OLD_TO_OLD>::RemoveRange(page, start, end,
5986c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                           SlotSet::FREE_EMPTY_BUCKETS);
5987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
5988109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
5989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid Heap::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo,
5991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   Object* value) {
5992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(InNewSpace(value));
5993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host));
5994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RelocInfo::Mode rmode = rinfo->rmode();
5995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Address addr = rinfo->pc();
5996f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SlotType slot_type = SlotTypeForRelocInfoMode(rmode);
5997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (rinfo->IsInConstantPool()) {
5998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    addr = rinfo->constant_pool_entry_address();
5999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (RelocInfo::IsCodeTarget(rmode)) {
6000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      slot_type = CODE_ENTRY_SLOT;
6001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
6002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DCHECK(RelocInfo::IsEmbeddedObject(rmode));
6003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      slot_type = OBJECT_SLOT;
6004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
6005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
6006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RememberedSet<OLD_TO_NEW>::InsertTyped(
6007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      source_page, reinterpret_cast<Address>(host), slot_type, addr);
6008f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
6009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
6010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid Heap::RecordWritesIntoCode(Code* code) {
6011f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  for (RelocIterator it(code, RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT));
6012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       !it.done(); it.next()) {
6013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    RecordWriteIntoCode(code, it.rinfo(), it.rinfo()->target_object());
6014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
6015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
6016f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
6017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpace* AllSpaces::next() {
6018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (counter_++) {
6019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NEW_SPACE:
6020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->new_space();
6021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
6022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return heap_->old_space();
6023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_SPACE:
6024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->code_space();
6025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case MAP_SPACE:
6026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->map_space();
6027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LO_SPACE:
6028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->lo_space();
6029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
6030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
6031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPagedSpace* PagedSpaces::next() {
6035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (counter_++) {
6036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
6037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return heap_->old_space();
6038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_SPACE:
6039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->code_space();
6040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case MAP_SPACE:
6041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->map_space();
6042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
6043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
6044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOldSpace* OldSpaces::next() {
6049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (counter_++) {
6050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
6051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return heap_->old_space();
6052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_SPACE:
6053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->code_space();
6054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
6055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
6056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpaceIterator::SpaceIterator(Heap* heap)
6060f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    : heap_(heap), current_space_(FIRST_SPACE - 1) {}
6061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpaceIterator::~SpaceIterator() {
6063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool SpaceIterator::has_next() {
6067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate until no more spaces.
6068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return current_space_ != LAST_SPACE;
6069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6071f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochSpace* SpaceIterator::next() {
6072f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(has_next());
6073f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return heap_->space(++current_space_);
6074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapObjectsFilter {
6078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
6079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~HeapObjectsFilter() {}
6080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool SkipObject(HeapObject* object) = 0;
6081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
6082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass UnreachableObjectsFilter : public HeapObjectsFilter {
6085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
6086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) {
6087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkReachableObjects();
6088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~UnreachableObjectsFilter() {
6091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_->mark_compact_collector()->ClearMarkbits();
6092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool SkipObject(HeapObject* object) {
6095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (object->IsFiller()) return true;
609662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return ObjectMarking::IsWhite(object);
6097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class MarkingVisitor : public ObjectVisitor {
6101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
6102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkingVisitor() : marking_stack_(10) {}
6103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void VisitPointers(Object** start, Object** end) override {
6105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (Object** p = start; p < end; p++) {
6106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!(*p)->IsHeapObject()) continue;
6107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HeapObject* obj = HeapObject::cast(*p);
610862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // Use Marking instead of ObjectMarking to avoid adjusting live bytes
610962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // counter.
6110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj);
6111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (Marking::IsWhite(mark_bit)) {
6112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Marking::WhiteToBlack(mark_bit);
6113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          marking_stack_.Add(obj);
6114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
6115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
6116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void TransitiveClosure() {
6119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      while (!marking_stack_.is_empty()) {
6120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HeapObject* obj = marking_stack_.RemoveLast();
6121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        obj->Iterate(this);
6122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
6123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
6126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    List<HeapObject*> marking_stack_;
6127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
6128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkReachableObjects() {
6130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkingVisitor visitor;
6131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_->IterateRoots(&visitor, VISIT_ALL);
6132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor.TransitiveClosure();
6133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap* heap_;
6136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation_;
6137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
6138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapIterator::HeapIterator(Heap* heap,
6140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HeapIterator::HeapObjectsFiltering filtering)
614162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    : no_heap_allocation_(),
6142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      heap_(heap),
6143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      filtering_(filtering),
6144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      filter_(nullptr),
6145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      space_iterator_(nullptr),
6146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_iterator_(nullptr) {
614762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  heap_->MakeHeapIterable();
6148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  heap_->heap_iterator_start();
6149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Start the iteration.
6150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  space_iterator_ = new SpaceIterator(heap_);
6151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (filtering_) {
6152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kFilterUnreachable:
6153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      filter_ = new UnreachableObjectsFilter(heap_);
6154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
6155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
6156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
6157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  object_iterator_ = space_iterator_->next()->GetObjectIterator();
6159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHeapIterator::~HeapIterator() {
6163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  heap_->heap_iterator_end();
6164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
6165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assert that in filtering mode we have iterated through all
6166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects. Otherwise, heap will be left in an inconsistent state.
6167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (filtering_ != kNoFiltering) {
6168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(object_iterator_ == nullptr);
6169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
6171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete space_iterator_;
6172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete filter_;
6173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapObject* HeapIterator::next() {
6177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (filter_ == nullptr) return NextObject();
6178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject* obj = NextObject();
6180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while ((obj != nullptr) && (filter_->SkipObject(obj))) obj = NextObject();
6181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj;
6182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapObject* HeapIterator::NextObject() {
6186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No iterator means we are done.
6187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (object_iterator_.get() == nullptr) return nullptr;
6188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (HeapObject* obj = object_iterator_.get()->Next()) {
6190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the current iterator has more objects we are fine.
6191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return obj;
6192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
6193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Go though the spaces looking for one that has objects.
6194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (space_iterator_->has_next()) {
6195f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      object_iterator_ = space_iterator_->next()->GetObjectIterator();
6196f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (HeapObject* obj = object_iterator_.get()->Next()) {
6197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return obj;
6198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
6199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Done with the last space.
6202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  object_iterator_.reset(nullptr);
6203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
6204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Heap::UpdateTotalGCTime(double duration) {
6208f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (FLAG_trace_gc_verbose) {
6209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    total_gc_time_ms_ += duration;
6210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
621362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::ExternalStringTable::CleanUpNewSpaceStrings() {
6214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int last = 0;
621513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Isolate* isolate = heap_->isolate();
6216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < new_space_strings_.length(); ++i) {
621762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Object* o = new_space_strings_[i];
621862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (o->IsTheHole(isolate)) {
6219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continue;
6220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
622162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (o->IsThinString()) {
622262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      o = ThinString::cast(o)->actual();
622362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (!o->IsExternalString()) continue;
622462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
622562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(o->IsExternalString());
622662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (heap_->InNewSpace(o)) {
622762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      new_space_strings_[last++] = o;
6228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
622962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      old_space_strings_.Add(o);
6230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_strings_.Rewind(last);
6233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_strings_.Trim();
623462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
6235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
623662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Heap::ExternalStringTable::CleanUpAll() {
623762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CleanUpNewSpaceStrings();
623862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int last = 0;
623962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Isolate* isolate = heap_->isolate();
6240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < old_space_strings_.length(); ++i) {
624162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Object* o = old_space_strings_[i];
624262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (o->IsTheHole(isolate)) {
6243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continue;
6244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
624562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (o->IsThinString()) {
624662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      o = ThinString::cast(o)->actual();
624762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (!o->IsExternalString()) continue;
624862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
624962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(o->IsExternalString());
625062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(!heap_->InNewSpace(o));
625162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    old_space_strings_[last++] = o;
6252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  old_space_strings_.Rewind(last);
6254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  old_space_strings_.Trim();
6255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
6256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
6257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Verify();
6258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
6260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ExternalStringTable::TearDown() {
6263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < new_space_strings_.length(); ++i) {
626462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Object* o = new_space_strings_[i];
626562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (o->IsThinString()) {
626662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      o = ThinString::cast(o)->actual();
626762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (!o->IsExternalString()) continue;
626862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
626962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    heap_->FinalizeExternalString(ExternalString::cast(o));
6270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_strings_.Free();
6272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < old_space_strings_.length(); ++i) {
627362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Object* o = old_space_strings_[i];
627462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (o->IsThinString()) {
627562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      o = ThinString::cast(o)->actual();
627662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (!o->IsExternalString()) continue;
627762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
627862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    heap_->FinalizeExternalString(ExternalString::cast(o));
6279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  old_space_strings_.Free();
6281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RememberUnmappedPage(Address page, bool compacted) {
6285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uintptr_t p = reinterpret_cast<uintptr_t>(page);
6286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Tag the page pointer to make it findable in the dump file.
6287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (compacted) {
6288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    p ^= 0xc1ead & (Page::kPageSize - 1);  // Cleared.
6289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
6290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    p ^= 0x1d1ed & (Page::kPageSize - 1);  // I died.
6291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  remembered_unmapped_pages_[remembered_unmapped_pages_index_] =
6293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<Address>(p);
6294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  remembered_unmapped_pages_index_++;
6295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  remembered_unmapped_pages_index_ %= kRememberedUnmappedPages;
6296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RegisterStrongRoots(Object** start, Object** end) {
6300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* list = new StrongRootsList();
6301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  list->next = strong_roots_list_;
6302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  list->start = start;
6303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  list->end = end;
6304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  strong_roots_list_ = list;
6305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::UnregisterStrongRoots(Object** start) {
6309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* prev = NULL;
6310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* list = strong_roots_list_;
6311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (list != nullptr) {
6312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StrongRootsList* next = list->next;
6313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (list->start == start) {
6314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (prev) {
6315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        prev->next = next;
6316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
6317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        strong_roots_list_ = next;
6318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
6319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      delete list;
6320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
6321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      prev = list;
6322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
6323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    list = next;
6324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
6325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochsize_t Heap::NumberOfTrackedHeapObjectTypes() {
6329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ObjectStats::OBJECT_STATS_COUNT;
6330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochsize_t Heap::ObjectCountAtLastGC(size_t index) {
6334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (live_object_stats_ == nullptr || index >= ObjectStats::OBJECT_STATS_COUNT)
6335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return 0;
6336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return live_object_stats_->object_count_last_gc(index);
6337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochsize_t Heap::ObjectSizeAtLastGC(size_t index) {
6341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (live_object_stats_ == nullptr || index >= ObjectStats::OBJECT_STATS_COUNT)
6342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return 0;
6343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return live_object_stats_->object_size_last_gc(index);
6344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::GetObjectTypeName(size_t index, const char** object_type,
6348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             const char** object_sub_type) {
6349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index >= ObjectStats::OBJECT_STATS_COUNT) return false;
6350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (static_cast<int>(index)) {
6352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define COMPARE_AND_RETURN_NAME(name) \
6353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case name:                          \
6354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_type = #name;             \
6355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_sub_type = "";            \
6356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
6357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    INSTANCE_TYPE_LIST(COMPARE_AND_RETURN_NAME)
6358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef COMPARE_AND_RETURN_NAME
6359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define COMPARE_AND_RETURN_NAME(name)                      \
6360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case ObjectStats::FIRST_CODE_KIND_SUB_TYPE + Code::name: \
6361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_type = "CODE_TYPE";                            \
6362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_sub_type = "CODE_KIND/" #name;                 \
6363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
6364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CODE_KIND_LIST(COMPARE_AND_RETURN_NAME)
6365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef COMPARE_AND_RETURN_NAME
6366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define COMPARE_AND_RETURN_NAME(name)                  \
6367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case ObjectStats::FIRST_FIXED_ARRAY_SUB_TYPE + name: \
6368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_type = "FIXED_ARRAY_TYPE";                 \
6369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_sub_type = #name;                          \
6370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
6371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COMPARE_AND_RETURN_NAME)
6372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef COMPARE_AND_RETURN_NAME
6373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define COMPARE_AND_RETURN_NAME(name)                                  \
6374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case ObjectStats::FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - \
6375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Code::kFirstCodeAge:                                             \
6376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_type = "CODE_TYPE";                                        \
6377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_sub_type = "CODE_AGE/" #name;                              \
6378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
6379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME)
6380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef COMPARE_AND_RETURN_NAME
6381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
6382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
6383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
6387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Heap::GetStaticVisitorIdForMap(Map* map) {
6388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return StaticVisitorBase::GetVisitorId(map);
6389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
6392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
6393