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