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