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 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/accessors.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/api.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/once.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/utils/random-number-generator.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bootstrapper.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compilation-cache.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/conversions.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/cpu-profiler.h" 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/debug.h" 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h" 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h" 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/gc-idle-time-handler.h" 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/incremental-marking.h" 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/mark-compact.h" 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/objects-visiting-inl.h" 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/objects-visiting.h" 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/store-buffer.h" 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap-profiler.h" 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate-inl.h" 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/natives.h" 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/runtime-profiler.h" 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scopeinfo.h" 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/snapshot.h" 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8threads.h" 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/vm-state-inl.h" 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/regexp-macro-assembler.h" // NOLINT 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/regexp-macro-assembler-arm.h" // NOLINT 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_MIPS && !V8_INTERPRETED_REGEXP 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/regexp-macro-assembler.h" // NOLINT 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips/regexp-macro-assembler-mips.h" // NOLINT 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_MIPS64 && !V8_INTERPRETED_REGEXP 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/regexp-macro-assembler.h" 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/regexp-macro-assembler-mips64.h" 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::Heap() 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : amount_of_external_allocated_memory_(0), 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch amount_of_external_allocated_memory_at_last_global_gc_(0), 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_(NULL), 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_range_size_(0), 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // semispace_size_ should be a power of 2 and old_generation_size_ should 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be a multiple of Page::kPageSize. 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reserved_semispace_size_(8 * (kPointerSize / 4) * MB), 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_semi_space_size_(8 * (kPointerSize / 4) * MB), 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial_semispace_size_(Page::kPageSize), 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_old_generation_size_(700ul * (kPointerSize / 4) * MB), 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_executable_size_(256ul * (kPointerSize / 4) * MB), 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Variables set based on semispace_size_ and old_generation_size_ in 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ConfigureHeap. 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Will be 4 * reserved_semispace_size_ to ensure that young 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generation can be aligned to its size. 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maximum_committed_(0), 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch survived_since_last_expansion_(0), 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sweep_generation_(0), 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch always_allocate_scope_depth_(0), 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch contexts_disposed_(0), 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_ic_age_(0), 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch flush_monomorphic_ics_(false), 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scan_on_scavenge_pages_(0), 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_(this), 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_(NULL), 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_(NULL), 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_(NULL), 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_(NULL), 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_(NULL), 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_(NULL), 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_(NULL), 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_state_(NOT_IN_GC), 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_post_processing_depth_(0), 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocations_count_(0), 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch raw_allocations_hash_(0), 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc), 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ms_count_(0), 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_count_(0), 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch remembered_unmapped_pages_index_(0), 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unflattened_strings_length_(0), 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_timeout_(0), 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // DEBUG 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit), 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_gen_exhausted_(false), 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline_allocation_disabled_(false), 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_rebuilder_(store_buffer()), 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hidden_string_(NULL), 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_safe_size_of_old_object_(NULL), 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_regexp_code_generated_(0), 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracer_(this), 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch high_survival_rate_period_length_(0), 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch promoted_objects_size_(0), 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch promotion_rate_(0), 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch semi_space_copied_object_size_(0), 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch semi_space_copied_rate_(0), 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch nodes_died_in_new_space_(0), 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch nodes_copied_in_new_space_(0), 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch nodes_promoted_(0), 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maximum_size_scavenges_(0), 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_gc_pause_(0.0), 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_gc_time_ms_(0.0), 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_alive_after_gc_(0), 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch min_in_mutator_(kMaxInt), 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch marking_time_(0.0), 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sweeping_time_(0.0), 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector_(this), 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_(this), 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch marking_(this), 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking_(this), 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_count_at_last_idle_gc_(0), 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch full_codegen_bytes_generated_(0), 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch crankshaft_codegen_bytes_generated_(0), 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gcs_since_last_deopt_(0), 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_weak_object_verification_scope_depth_(0), 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_sites_scratchpad_length_(0), 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch promotion_queue_(this), 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch configured_(false), 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_string_table_(this), 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunks_queued_for_free_(NULL), 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_callbacks_depth_(0) { 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Allow build-time customization of the max semispace size. Building 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// V8 with snapshots and a non-default max semispace size is much 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// easier if you can define it as part of the build environment. 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(V8_MAX_SEMISPACE_SIZE) 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ensure old_generation_size_ is a multiple of kPageSize. 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(MB >= Page::kPageSize); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memset(roots_, 0, sizeof(roots_[0]) * kRootListLength); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_native_contexts_list(NULL); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_array_buffers_list(Smi::FromInt(0)); 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_allocation_sites_list(Smi::FromInt(0)); 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_encountered_weak_collections(Smi::FromInt(0)); 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put a dummy entry in the remembered pages so we can find the list the 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // minidump even if there are no real unmapped pages. 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberUnmappedPage(NULL, false); 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearObjectStats(true); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::Capacity() { 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!HasBeenSetUp()) return 0; 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_space_.Capacity() + old_pointer_space_->Capacity() + 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->Capacity() + code_space_->Capacity() + 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->Capacity() + cell_space_->Capacity() + 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->Capacity(); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::CommittedMemory() { 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!HasBeenSetUp()) return 0; 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_space_.CommittedMemory() + old_pointer_space_->CommittedMemory() + 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->CommittedMemory() + code_space_->CommittedMemory() + 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->CommittedMemory() + cell_space_->CommittedMemory() + 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->CommittedMemory() + lo_space_->Size(); 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t Heap::CommittedPhysicalMemory() { 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!HasBeenSetUp()) return 0; 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_space_.CommittedPhysicalMemory() + 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->CommittedPhysicalMemory() + 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->CommittedPhysicalMemory() + 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_->CommittedPhysicalMemory() + 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->CommittedPhysicalMemory() + 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_->CommittedPhysicalMemory() + 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->CommittedPhysicalMemory() + 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_->CommittedPhysicalMemory(); 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::CommittedMemoryExecutable() { 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!HasBeenSetUp()) return 0; 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return isolate()->memory_allocator()->SizeExecutable(); 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateMaximumCommitted() { 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!HasBeenSetUp()) return; 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t current_committed_memory = CommittedMemory(); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_committed_memory > maximum_committed_) { 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maximum_committed_ = current_committed_memory; 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::Available() { 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!HasBeenSetUp()) return 0; 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_space_.Available() + old_pointer_space_->Available() + 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->Available() + code_space_->Available() + 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->Available() + cell_space_->Available() + 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->Available(); 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::HasBeenSetUp() { 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return old_pointer_space_ != NULL && old_data_space_ != NULL && 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_ != NULL && map_space_ != NULL && cell_space_ != NULL && 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_ != NULL && lo_space_ != NULL; 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Heap::GcSafeSizeOfOldObject(HeapObject* object) { 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IntrusiveMarking::IsMarked(object)) { 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IntrusiveMarking::SizeOfMarkedObject(object); 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object->SizeFromMap(object->map()); 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochGarbageCollector Heap::SelectGarbageCollector(AllocationSpace space, 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char** reason) { 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Is global GC requested? 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (space != NEW_SPACE) { 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->gc_compactor_caused_by_request()->Increment(); 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reason = "GC in old space requested"; 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MARK_COMPACTOR; 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) { 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reason = "GC in old space forced by flags"; 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MARK_COMPACTOR; 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Is enough data promoted to justify a global GC? 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (OldGenerationAllocationLimitReached()) { 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->gc_compactor_caused_by_promoted_data()->Increment(); 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reason = "promotion limit reached"; 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MARK_COMPACTOR; 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Have allocation in OLD and LO failed? 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (old_gen_exhausted_) { 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters() 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->gc_compactor_caused_by_oldspace_exhaustion() 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Increment(); 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reason = "old generations exhausted"; 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MARK_COMPACTOR; 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Is there enough space left in OLD to guarantee that a scavenge can 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // succeed? 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note that MemoryAllocator->MaxAvailable() undercounts the memory available 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for object promotion. It counts only the bytes that the memory 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocator has not yet allocated from the OS and assigned to any space, 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and does not count available bytes already in the old space or code 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // space. Undercounting is safe---we may get an unrequested full GC when 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a scavenge would have succeeded. 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate_->memory_allocator()->MaxAvailable() <= new_space_.Size()) { 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters() 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->gc_compactor_caused_by_oldspace_exhaustion() 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Increment(); 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reason = "scavenge might not succeed"; 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MARK_COMPACTOR; 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Default 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reason = NULL; 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SCAVENGER; 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(1238405): Combine the infrastructure for --heap-stats and 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --log-gc to avoid the complicated preprocessor and flag testing. 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportStatisticsBeforeGC() { 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Heap::ReportHeapStatistics will also log NewSpace statistics when 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// compiled --log-gc is set. The following logic is used to avoid 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// double logging. 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_heap_stats || FLAG_log_gc) new_space_.CollectStatistics(); 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_heap_stats) { 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReportHeapStatistics("Before GC"); 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (FLAG_log_gc) { 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.ReportStatistics(); 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_heap_stats || FLAG_log_gc) new_space_.ClearHistograms(); 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_log_gc) { 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.CollectStatistics(); 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.ReportStatistics(); 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.ClearHistograms(); 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // DEBUG 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::PrintShortHeapStatistics() { 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_trace_gc_verbose) return; 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("Memory allocator, used: %6" V8_PTR_PREFIX 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX "d KB\n", 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->memory_allocator()->Size() / KB, 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->memory_allocator()->Available() / KB); 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("New space, used: %6" V8_PTR_PREFIX 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", committed: %6" V8_PTR_PREFIX "d KB\n", 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.Size() / KB, new_space_.Available() / KB, 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.CommittedMemory() / KB); 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("Old pointers, used: %6" V8_PTR_PREFIX 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", committed: %6" V8_PTR_PREFIX "d KB\n", 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->SizeOfObjects() / KB, 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->Available() / KB, 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->CommittedMemory() / KB); 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("Old data space, used: %6" V8_PTR_PREFIX 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", committed: %6" V8_PTR_PREFIX "d KB\n", 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->SizeOfObjects() / KB, 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->Available() / KB, 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->CommittedMemory() / KB); 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("Code space, used: %6" V8_PTR_PREFIX 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", committed: %6" V8_PTR_PREFIX "d KB\n", 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_->SizeOfObjects() / KB, code_space_->Available() / KB, 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_->CommittedMemory() / KB); 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("Map space, used: %6" V8_PTR_PREFIX 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", committed: %6" V8_PTR_PREFIX "d KB\n", 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->SizeOfObjects() / KB, map_space_->Available() / KB, 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->CommittedMemory() / KB); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("Cell space, used: %6" V8_PTR_PREFIX 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", committed: %6" V8_PTR_PREFIX "d KB\n", 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_->SizeOfObjects() / KB, cell_space_->Available() / KB, 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_->CommittedMemory() / KB); 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("PropertyCell space, used: %6" V8_PTR_PREFIX 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", committed: %6" V8_PTR_PREFIX "d KB\n", 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->SizeOfObjects() / KB, 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->Available() / KB, 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->CommittedMemory() / KB); 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("Large object space, used: %6" V8_PTR_PREFIX 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", committed: %6" V8_PTR_PREFIX "d KB\n", 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_->SizeOfObjects() / KB, lo_space_->Available() / KB, 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_->CommittedMemory() / KB); 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("All spaces, used: %6" V8_PTR_PREFIX 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", available: %6" V8_PTR_PREFIX 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "d KB" 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ", committed: %6" V8_PTR_PREFIX "d KB\n", 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->SizeOfObjects() / KB, this->Available() / KB, 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->CommittedMemory() / KB); 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("External memory reported: %6" V8_PTR_PREFIX "d KB\n", 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<intptr_t>(amount_of_external_allocated_memory_ / KB)); 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("Total time spent in GC : %.1f ms\n", total_gc_time_ms_); 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(1238405): Combine the infrastructure for --heap-stats and 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --log-gc to avoid the complicated preprocessor and flag testing. 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportStatisticsAfterGC() { 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Similar to the before GC, we use some complicated logic to ensure that 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NewSpace statistics are logged exactly once when --log-gc is turned on. 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(DEBUG) 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_heap_stats) { 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.CollectStatistics(); 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReportHeapStatistics("After GC"); 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (FLAG_log_gc) { 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.ReportStatistics(); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_log_gc) new_space_.ReportStatistics(); 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // DEBUG 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::GarbageCollectionPrologue() { 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHeapAllocation for_the_first_part_of_prologue; 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearJSFunctionResultCaches(); 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_count_++; 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unflattened_strings_length_ = 0; 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_flush_code && FLAG_flush_code_incrementally) { 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->EnableCodeFlushing(true); 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_heap) { 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Verify(); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Reset GC statistics. 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch promoted_objects_size_ = 0; 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 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer()->GCPrologue(); 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate()->concurrent_osr_enabled()) { 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->optimizing_compiler_thread()->AgeBufferedOsrJobs(); 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (new_space_.IsAtMaximumCapacity()) { 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maximum_size_scavenges_++; 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maximum_size_scavenges_ = 0; 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckNewSpaceExpansionCriteria(); 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::SizeOfObjects() { 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t total = 0; 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllSpaces spaces(this); 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total += space->SizeOfObjects(); 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return total; 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ClearAllICsByKind(Code::Kind kind) { 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectIterator it(code_space()); 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object* object = it.Next(); object != NULL; object = it.Next()) { 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* code = Code::cast(object); 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code::Kind current_kind = code->kind(); 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_kind == Code::FUNCTION || 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_kind == Code::OPTIMIZED_FUNCTION) { 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->ClearInlineCaches(kind); 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RepairFreeListsAfterBoot() { 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PagedSpaces spaces(this); 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (PagedSpace* space = spaces.next(); space != NULL; 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space = spaces.next()) { 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space->RepairFreeListsAfterBoot(); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessPretenuringFeedback() { 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring) { 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int tenure_decisions = 0; 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int dont_tenure_decisions = 0; 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int allocation_mementos_found = 0; 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int allocation_sites = 0; 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int active_allocation_sites = 0; 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the scratchpad overflowed, we have to iterate over the allocation 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sites list. 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(hpayer): We iterate over the whole list of allocation sites when 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we grew to the maximum semi-space size to deopt maybe tenured 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocation sites. We could hold the maybe tenured allocation sites 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in a seperate data structure if this is a performance problem. 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool deopt_maybe_tenured = DeoptMaybeTenuredAllocationSites(); 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool use_scratchpad = 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_sites_scratchpad_length_ < kAllocationSiteScratchpadSize && 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !deopt_maybe_tenured; 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int i = 0; 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* list_element = allocation_sites_list(); 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool trigger_deoptimization = false; 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool maximum_size_scavenge = MaximumSizeScavenge(); 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (use_scratchpad ? i < allocation_sites_scratchpad_length_ 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : list_element->IsAllocationSite()) { 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite* site = 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_scratchpad 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? AllocationSite::cast(allocation_sites_scratchpad()->get(i)) 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : AllocationSite::cast(list_element); 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_mementos_found += site->memento_found_count(); 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (site->memento_found_count() > 0) { 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch active_allocation_sites++; 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (site->DigestPretenuringFeedback(maximum_size_scavenge)) { 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trigger_deoptimization = true; 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (site->GetPretenureMode() == TENURED) { 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tenure_decisions++; 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dont_tenure_decisions++; 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_sites++; 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (deopt_maybe_tenured && site->IsMaybeTenure()) { 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site->set_deopt_dependent_code(true); 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trigger_deoptimization = true; 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (use_scratchpad) { 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i++; 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list_element = site->weak_next(); 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (trigger_deoptimization) { 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->stack_guard()->RequestDeoptMarkedAllocationSites(); 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlushAllocationSitesScratchpad(); 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_pretenuring_statistics && 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (allocation_mementos_found > 0 || tenure_decisions > 0 || 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dont_tenure_decisions > 0)) { 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF( 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "GC: (mode, #visited allocation sites, #active allocation sites, " 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "#mementos, #tenure decisions, #donttenure decisions) " 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "(%s, %d, %d, %d, %d, %d)\n", 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_scratchpad ? "use scratchpad" : "use list", allocation_sites, 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch active_allocation_sites, allocation_mementos_found, tenure_decisions, 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dont_tenure_decisions); 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::DeoptMarkedAllocationSites() { 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(hpayer): If iterating over the allocation sites list becomes a 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // performance issue, use a cache heap data structure instead (similar to the 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocation sites scratchpad). 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* list_element = allocation_sites_list(); 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (list_element->IsAllocationSite()) { 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite* site = AllocationSite::cast(list_element); 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (site->deopt_dependent_code()) { 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site->dependent_code()->MarkCodeForDeoptimization( 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_, DependentCode::kAllocationSiteTenuringChangedGroup); 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site->set_deopt_dependent_code(false); 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list_element = site->weak_next(); 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::DeoptimizeMarkedCode(isolate_); 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::GarbageCollectionEpilogue() { 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer()->GCEpilogue(); 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In release mode, we only zap the from space under heap verification. 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Heap::ShouldZapGarbage()) { 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZapFromSpace(); 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Process pretenuring feedback and update allocation sites. 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessPretenuringFeedback(); 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_heap) { 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Verify(); 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHeapAllocation for_the_rest_of_the_epilogue; 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_print_global_handles) isolate_->global_handles()->Print(); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_print_handles) PrintHandles(); 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_gc_verbose) Print(); 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_code_stats) ReportCodeStatistics("After GC"); 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_deopt_every_n_garbage_collections > 0) { 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(jkummerow/ulan/jarin): This is not safe! We can't assume that 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the topmost optimized frame can be deoptimized safely, because it 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // might not have a lazy bailout point right after its current PC. 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (++gcs_since_last_deopt_ == FLAG_deopt_every_n_garbage_collections) { 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::DeoptimizeAll(isolate()); 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gcs_since_last_deopt_ = 0; 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateMaximumCommitted(); 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->alive_after_last_gc()->Set( 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(SizeOfObjects())); 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->string_table_capacity()->Set( 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string_table()->Capacity()); 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->number_of_symbols()->Set( 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string_table()->NumberOfElements()); 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (full_codegen_bytes_generated_ + crankshaft_codegen_bytes_generated_ > 0) { 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->codegen_fraction_crankshaft()->AddSample( 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>((crankshaft_codegen_bytes_generated_ * 100.0) / 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (crankshaft_codegen_bytes_generated_ + 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch full_codegen_bytes_generated_))); 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (CommittedMemory() > 0) { 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->external_fragmentation_total()->AddSample( 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(100 - (SizeOfObjects() * 100.0) / CommittedMemory())); 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_fraction_new_space()->AddSample(static_cast<int>( 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (new_space()->CommittedMemory() * 100.0) / CommittedMemory())); 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_fraction_old_pointer_space()->AddSample( 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>((old_pointer_space()->CommittedMemory() * 100.0) / 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CommittedMemory())); 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_fraction_old_data_space()->AddSample( 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>((old_data_space()->CommittedMemory() * 100.0) / 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CommittedMemory())); 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_fraction_code_space()->AddSample( 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>((code_space()->CommittedMemory() * 100.0) / 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CommittedMemory())); 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_fraction_map_space()->AddSample(static_cast<int>( 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (map_space()->CommittedMemory() * 100.0) / CommittedMemory())); 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_fraction_cell_space()->AddSample( 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>((cell_space()->CommittedMemory() * 100.0) / 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CommittedMemory())); 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_fraction_property_cell_space()->AddSample( 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>((property_cell_space()->CommittedMemory() * 100.0) / 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CommittedMemory())); 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_fraction_lo_space()->AddSample(static_cast<int>( 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (lo_space()->CommittedMemory() * 100.0) / CommittedMemory())); 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_sample_total_committed()->AddSample( 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(CommittedMemory() / KB)); 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_sample_total_used()->AddSample( 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(SizeOfObjects() / KB)); 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_sample_map_space_committed()->AddSample( 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(map_space()->CommittedMemory() / KB)); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_sample_cell_space_committed()->AddSample( 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(cell_space()->CommittedMemory() / KB)); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters() 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->heap_sample_property_cell_space_committed() 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->AddSample( 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(property_cell_space()->CommittedMemory() / KB)); 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_sample_code_space_committed()->AddSample( 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(code_space()->CommittedMemory() / KB)); 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->heap_sample_maximum_committed()->AddSample( 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(MaximumCommittedMemory() / KB)); 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UPDATE_COUNTERS_FOR_SPACE(space) \ 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->space##_bytes_available()->Set( \ 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(space()->Available())); \ 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->space##_bytes_committed()->Set( \ 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(space()->CommittedMemory())); \ 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->space##_bytes_used()->Set( \ 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(space()->SizeOfObjects())); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UPDATE_FRAGMENTATION_FOR_SPACE(space) \ 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (space()->CommittedMemory() > 0) { \ 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->external_fragmentation_##space()->AddSample( \ 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(100 - \ 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (space()->SizeOfObjects() * 100.0) / \ 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space()->CommittedMemory())); \ 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(space) \ 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_COUNTERS_FOR_SPACE(space) \ 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_FRAGMENTATION_FOR_SPACE(space) 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_COUNTERS_FOR_SPACE(new_space) 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_pointer_space) 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_data_space) 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(code_space) 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(map_space) 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(cell_space) 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(property_cell_space) 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(lo_space) 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef UPDATE_COUNTERS_FOR_SPACE 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef UPDATE_FRAGMENTATION_FOR_SPACE 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReportStatisticsAfterGC(); 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // DEBUG 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remember the last top pointer so that we can later find out 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // whether we allocated in new space since the last GC. 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_top_after_last_gc_ = new_space()->top(); 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CollectAllGarbage(int flags, const char* gc_reason, 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::GCCallbackFlags gc_callback_flags) { 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since we are ignoring the return value, the exact choice of space does 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // not matter, so long as we do not specify NEW_SPACE, which would not 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // cause a full GC. 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector_.SetFlags(flags); 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CollectGarbage(OLD_POINTER_SPACE, gc_reason, gc_callback_flags); 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector_.SetFlags(kNoGCFlags); 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CollectAllAvailableGarbage(const char* gc_reason) { 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since we are ignoring the return value, the exact choice of space does 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // not matter, so long as we do not specify NEW_SPACE, which would not 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // cause a full GC. 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Major GC would invoke weak handle callbacks on weakly reachable 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // handles, but won't collect weakly reachable objects until next 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // major GC. Therefore if we collect aggressively and weak handle callback 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // has been invoked, we rerun major GC to release objects which become 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // garbage. 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note: as weak callbacks can execute arbitrary code, we cannot 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hope that eventually there will be no weak callbacks invocations. 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Therefore stop recollecting after several attempts. 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate()->concurrent_recompilation_enabled()) { 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The optimizing compiler may be unnecessarily holding on to memory. 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_recursive_gc; 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->optimizing_compiler_thread()->Flush(); 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->SetFlags(kMakeHeapIterableMask | 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kReduceMemoryFootprintMask); 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->compilation_cache()->Clear(); 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kMaxNumberOfAttempts = 7; 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kMinNumberOfAttempts = 2; 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) { 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CollectGarbage(MARK_COMPACTOR, gc_reason, NULL) && 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch attempt + 1 >= kMinNumberOfAttempts) { 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->SetFlags(kNoGCFlags); 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.Shrink(); 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UncommitFromSpace(); 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->UncommitMarkingDeque(); 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnsureFillerObjectAtTop() { 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There may be an allocation memento behind every object in new space. 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we evacuate a not full new space or if we are on the last page of 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the new space, then there may be uninitialized memory behind the top 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pointer of the new space page. We store a filler object there to 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // identify the unused space. 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address from_top = new_space_.top(); 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address from_limit = new_space_.limit(); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (from_top < from_limit) { 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int remaining_in_page = static_cast<int>(from_limit - from_top); 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateFillerObjectAt(from_top, remaining_in_page); 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason, 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* collector_reason, 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::GCCallbackFlags gc_callback_flags) { 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The VM is in the GC state until exiting this function. 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VMState<GC> state(isolate_); 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Reset the allocation timeout to the GC interval, but make sure to 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allow at least a few allocations after a collection. The reason 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for this is that we have a lot of allocation sequences and we 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // assume that a garbage collection will allow the subsequent 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocation attempts to go through. 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_timeout_ = Max(6, FLAG_gc_interval); 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnsureFillerObjectAtTop(); 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (collector == SCAVENGER && !incremental_marking()->IsStopped()) { 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_incremental_marking) { 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("[IncrementalMarking] Scavenge during marking.\n"); 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (collector == MARK_COMPACTOR && 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !mark_compact_collector()->abort_incremental_marking() && 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !incremental_marking()->IsStopped() && 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !incremental_marking()->should_hurry() && 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_incremental_marking_steps) { 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make progress in incremental marking. 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const intptr_t kStepSizeWhenDelayedByScavenge = 1 * MB; 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->Step(kStepSizeWhenDelayedByScavenge, 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementalMarking::NO_GC_VIA_STACK_GUARD); 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!incremental_marking()->IsComplete() && !FLAG_gc_global) { 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_incremental_marking) { 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("[IncrementalMarking] Delaying MarkSweep.\n"); 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collector = SCAVENGER; 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collector_reason = "incremental marking delaying mark-sweep"; 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool next_gc_likely_to_collect_more = false; 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracer()->Start(collector, gc_reason, collector_reason); 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AllowHeapAllocation::IsAllowed()); 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation_during_gc; 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GarbageCollectionPrologue(); 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HistogramTimerScope histogram_timer_scope( 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (collector == SCAVENGER) ? isolate_->counters()->gc_scavenger() 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : isolate_->counters()->gc_compactor()); 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_gc_likely_to_collect_more = 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PerformGarbageCollection(collector, gc_callback_flags); 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GarbageCollectionEpilogue(); 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracer()->Stop(); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Start incremental marking for the next cycle. The heap snapshot 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generator needs incremental marking to stay off after it aborted. 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!mark_compact_collector()->abort_incremental_marking() && 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WorthActivatingIncrementalMarking()) { 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->Start(); 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next_gc_likely_to_collect_more; 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Heap::NotifyContextDisposed() { 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate()->concurrent_recompilation_enabled()) { 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Flush the queued recompilation tasks. 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->optimizing_compiler_thread()->Flush(); 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch flush_monomorphic_ics_ = true; 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AgeInlineCaches(); 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ++contexts_disposed_; 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MoveElements(FixedArray* array, int dst_index, int src_index, 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int len) { 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (len == 0) return; 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(array->map() != fixed_cow_array_map()); 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** dst_objects = array->data_start() + dst_index; 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!InNewSpace(array)) { 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < len; i++) { 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(hpayer): check store buffer for entries 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (InNewSpace(dst_objects[i])) { 879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrite(array->address(), array->OffsetOfElementAt(dst_index + i)); 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->RecordWrites(array); 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper class for verifying the string table. 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StringTableVerifier : public ObjectVisitor { 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitPointers(Object** start, Object** end) { 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit all HeapObject pointers in [start, end). 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; p < end; p++) { 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*p)->IsHeapObject()) { 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the string is actually internalized. 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK((*p)->IsTheHole() || (*p)->IsUndefined() || 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (*p)->IsInternalizedString()); 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void VerifyStringTable(Heap* heap) { 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StringTableVerifier verifier; 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->string_table()->IterateElements(&verifier); 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // VERIFY_HEAP 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool AbortIncrementalMarkingAndCollectGarbage( 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap, AllocationSpace space, const char* gc_reason = NULL) { 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->mark_compact_collector()->SetFlags(Heap::kAbortIncrementalMarkingMask); 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool result = heap->CollectGarbage(space, gc_reason); 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->mark_compact_collector()->SetFlags(Heap::kNoGCFlags); 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReserveSpace(int* sizes, Address* locations_out) { 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool gc_performed = true; 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int counter = 0; 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kThreshold = 20; 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (gc_performed && counter++ < kThreshold) { 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_performed = false; 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(NEW_SPACE == FIRST_PAGED_SPACE - 1); 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int space = NEW_SPACE; space <= LAST_PAGED_SPACE; space++) { 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (sizes[space] != 0) { 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation; 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (space == NEW_SPACE) { 931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = new_space()->AllocateRaw(sizes[space]); 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = paged_space(space)->AllocateRaw(sizes[space]); 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FreeListNode* node; 936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&node)) { 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (space == NEW_SPACE) { 938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::CollectGarbage(NEW_SPACE, 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "failed to reserve space in the new space"); 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AbortIncrementalMarkingAndCollectGarbage( 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this, static_cast<AllocationSpace>(space), 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "failed to reserve space in paged space"); 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_performed = true; 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark with a free list node, in case we have a GC before 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // deserializing. 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node->set_size(this, sizes[space]); 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch locations_out[space] = node->address(); 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (gc_performed) { 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Failed to reserve the space after several attempts. 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V8::FatalProcessOutOfMemory("Heap::ReserveSpace"); 960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnsureFromSpaceIsCommitted() { 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (new_space_.CommitFromSpaceIfNeeded()) return; 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Committing memory to from space failed. 968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Memory is exhausted and we will die. 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V8::FatalProcessOutOfMemory("Committing semi space failed."); 970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ClearJSFunctionResultCaches() { 974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate_->bootstrapper()->IsActive()) return; 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* context = native_contexts_list(); 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!context->IsUndefined()) { 978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the caches for this context. GC can happen when the context 979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is not fully initialized, so the caches can be undefined. 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* caches_or_undefined = 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Context::cast(context)->get(Context::JSFUNCTION_RESULT_CACHES_INDEX); 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!caches_or_undefined->IsUndefined()) { 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* caches = FixedArray::cast(caches_or_undefined); 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clear the caches: 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = caches->length(); 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < length; i++) { 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunctionResultCache::cast(caches->get(i))->Clear(); 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the next context: 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ClearNormalizedMapCaches() { 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate_->bootstrapper()->IsActive() && 998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !incremental_marking()->IsMarking()) { 999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* context = native_contexts_list(); 1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!context->IsUndefined()) { 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // GC can happen when the context is not fully initialized, 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // so the cache can be undefined. 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* cache = 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX); 1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!cache->IsUndefined()) { 1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NormalizedMapCache::cast(cache)->Clear(); 1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateSurvivalStatistics(int start_new_space_size) { 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (start_new_space_size == 0) return; 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch promotion_rate_ = (static_cast<double>(promoted_objects_size_) / 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<double>(start_new_space_size) * 100); 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch semi_space_copied_rate_ = 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (static_cast<double>(semi_space_copied_object_size_) / 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<double>(start_new_space_size) * 100); 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double survival_rate = promotion_rate_ + semi_space_copied_rate_; 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (survival_rate > kYoungSurvivalRateHighThreshold) { 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch high_survival_rate_period_length_++; 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch high_survival_rate_period_length_ = 0; 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::PerformGarbageCollection( 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) { 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int freed_global_handles = 0; 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (collector != SCAVENGER) { 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROFILE(isolate_, CodeMovingGCEvent()); 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_heap) { 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VerifyStringTable(this); 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCType gc_type = 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCCallbacksScope scope(this); 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope.CheckReenter()) { 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHeapAllocation allow_allocation; 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VMState<EXTERNAL> state(isolate_); 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope handle_scope(isolate_); 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags); 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnsureFromSpaceIsCommitted(); 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start_new_space_size = Heap::new_space()->SizeAsInt(); 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsHighSurvivalRate()) { 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We speed up the incremental marker if it is running so that it 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // does not fall behind the rate of promotion, which would cause a 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // constantly growing old space. 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->NotifyOfHighPromotionRate(); 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (collector == MARK_COMPACTOR) { 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform mark-sweep with optional compaction. 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkCompact(); 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sweep_generation_++; 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Temporarily set the limit for case when PostGarbageCollectionProcessing 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocates and triggers GC. The real limit is set at after 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // PostGarbageCollectionProcessing. 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_generation_allocation_limit_ = 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0); 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_gen_exhausted_ = false; 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scavenge(); 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateSurvivalStatistics(start_new_space_size); 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->objs_since_last_young()->Set(0); 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Callbacks that fire after this point might trigger nested GCs and 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // restart incremental marking, the assertion can't be moved down. 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(collector == SCAVENGER || incremental_marking()->IsStopped()); 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_post_processing_depth_++; 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHeapAllocation allow_allocation; 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch freed_global_handles = 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->global_handles()->PostGarbageCollectionProcessing(collector); 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_post_processing_depth_--; 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->eternal_handles()->PostGarbageCollectionProcessing(this); 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update relocatables. 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Relocatable::PostGarbageCollectionProcessing(isolate_); 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (collector == MARK_COMPACTOR) { 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register the amount of external allocated memory. 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch amount_of_external_allocated_memory_at_last_global_gc_ = 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch amount_of_external_allocated_memory_; 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_generation_allocation_limit_ = OldGenerationAllocationLimit( 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PromotedSpaceSizeOfObjects(), freed_global_handles); 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCCallbacksScope scope(this); 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope.CheckReenter()) { 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHeapAllocation allow_allocation; 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VMState<EXTERNAL> state(isolate_); 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope handle_scope(isolate_); 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallGCEpilogueCallbacks(gc_type, gc_callback_flags); 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_heap) { 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VerifyStringTable(this); 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return freed_global_handles > 0; 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) { 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) { 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (gc_type & gc_prologue_callbacks_[i].gc_type) { 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!gc_prologue_callbacks_[i].pass_isolate_) { 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::GCPrologueCallback callback = 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<v8::GCPrologueCallback>( 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_prologue_callbacks_[i].callback); 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch callback(gc_type, flags); 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate()); 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_prologue_callbacks_[i].callback(isolate, gc_type, flags); 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CallGCEpilogueCallbacks(GCType gc_type, 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCCallbackFlags gc_callback_flags) { 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (gc_type & gc_epilogue_callbacks_[i].gc_type) { 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!gc_epilogue_callbacks_[i].pass_isolate_) { 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::GCPrologueCallback callback = 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<v8::GCPrologueCallback>( 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_epilogue_callbacks_[i].callback); 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch callback(gc_type, gc_callback_flags); 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate()); 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_epilogue_callbacks_[i].callback(isolate, gc_type, gc_callback_flags); 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MarkCompact() { 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_state_ = MARK_COMPACT; 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG(isolate_, ResourceEvent("markcompact", "begin")); 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t size_of_objects_before_gc = SizeOfObjects(); 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector_.Prepare(); 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ms_count_++; 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkCompactPrologue(); 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector_.CollectGarbage(); 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG(isolate_, ResourceEvent("markcompact", "end")); 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_state_ = NOT_IN_GC; 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->objs_since_last_full()->Set(0); 1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch flush_monomorphic_ics_ = false; 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring) { 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvaluateOldSpaceLocalPretenuring(size_of_objects_before_gc); 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MarkCompactPrologue() { 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // At any old GC clear the keyed lookup cache to enable collection of unused 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // maps. 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->keyed_lookup_cache()->Clear(); 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->context_slot_cache()->Clear(); 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->descriptor_lookup_cache()->Clear(); 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegExpResultsCache::Clear(string_split_cache()); 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegExpResultsCache::Clear(regexp_multiple_cache()); 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->compilation_cache()->MarkCompactPrologue(); 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompletelyClearInstanceofCache(); 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlushNumberStringCache(); 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_cleanup_code_caches_at_gc) { 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch polymorphic_code_cache()->set_cache(undefined_value()); 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearNormalizedMapCaches(); 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper class for copying HeapObjects 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ScavengeVisitor : public ObjectVisitor { 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit ScavengeVisitor(Heap* heap) : heap_(heap) {} 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitPointer(Object** p) { ScavengePointer(p); } 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitPointers(Object** start, Object** end) { 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy all HeapObject pointers in [start, end) 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; p < end; p++) ScavengePointer(p); 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ScavengePointer(Object** p) { 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* object = *p; 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!heap_->InNewSpace(object)) return; 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<HeapObject*>(object)); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Visitor class to verify pointers in code or data space do not point into 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// new space. 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass VerifyNonPointerSpacePointersVisitor : public ObjectVisitor { 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit VerifyNonPointerSpacePointersVisitor(Heap* heap) : heap_(heap) {} 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitPointers(Object** start, Object** end) { 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** current = start; current < end; current++) { 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*current)->IsHeapObject()) { 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!heap_->InNewSpace(HeapObject::cast(*current))); 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void VerifyNonPointerSpacePointers(Heap* heap) { 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Verify that there are no pointers to new space in spaces where we 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // do not expect them. 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VerifyNonPointerSpacePointersVisitor v(heap); 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectIterator code_it(heap->code_space()); 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HeapObject* object = code_it.Next(); object != NULL; 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object = code_it.Next()) 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->Iterate(&v); 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectIterator data_it(heap->old_data_space()); 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HeapObject* object = data_it.Next(); object != NULL; 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object = data_it.Next()) 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->Iterate(&v); 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // VERIFY_HEAP 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CheckNewSpaceExpansionCriteria() { 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch survived_since_last_expansion_ > new_space_.TotalCapacity()) { 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Grow the size of new space if there is room to grow, enough data 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // has survived scavenge since the last expansion and we are not in 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // high promotion mode. 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.Grow(); 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch survived_since_last_expansion_ = 0; 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool IsUnscavengedHeapObject(Heap* heap, Object** p) { 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap->InNewSpace(*p) && 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !HeapObject::cast(*p)->map_word().IsForwardingAddress(); 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ScavengeStoreBufferCallback(Heap* heap, MemoryChunk* page, 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreBufferEvent event) { 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->store_buffer_rebuilder_.Callback(page, event); 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid StoreBufferRebuilder::Callback(MemoryChunk* page, StoreBufferEvent event) { 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (event == kStoreBufferStartScanningPagesEvent) { 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_of_current_page_ = NULL; 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_page_ = NULL; 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (event == kStoreBufferScanningPageEvent) { 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_page_ != NULL) { 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If this page already overflowed the store buffer during this iteration. 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_page_->scan_on_scavenge()) { 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Then we should wipe out the entries that have been added for it. 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_->SetTop(start_of_current_page_); 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (store_buffer_->Top() - start_of_current_page_ >= 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (store_buffer_->Limit() - store_buffer_->Top()) >> 2) { 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Did we find too many pointers in the previous page? The heuristic is 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that no page can take more then 1/5 the remaining slots in the store 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // buffer. 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_page_->set_scan_on_scavenge(true); 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_->SetTop(start_of_current_page_); 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In this case the page we scanned took a reasonable number of slots in 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the store buffer. It has now been rehabilitated and is no longer 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // marked scan_on_scavenge. 1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!current_page_->scan_on_scavenge()); 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_of_current_page_ = store_buffer_->Top(); 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_page_ = page; 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (event == kStoreBufferFullEvent) { 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The current page overflowed the store buffer again. Wipe out its entries 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in the store buffer and mark it scan-on-scavenge again. This may happen 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // several times while scanning. 1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_page_ == NULL) { 1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store Buffer overflowed while scanning promoted objects. These are not 1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in any particular page, though they are likely to be clustered by the 1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocation routines. 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_->EnsureSpace(StoreBuffer::kStoreBufferSize / 2); 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store Buffer overflowed while scanning a particular old space page for 1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pointers to new space. 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_page_ == page); 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(page != NULL); 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_page_->set_scan_on_scavenge(true); 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(start_of_current_page_ != store_buffer_->Top()); 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_->SetTop(start_of_current_page_); 1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PromotionQueue::Initialize() { 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Assumes that a NewSpacePage exactly fits a number of promotion queue 1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // entries (where each is a pair of intptr_t). This allows us to simplify 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the test fpr when to switch pages. 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) == 1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0); 1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch limit_ = reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceStart()); 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch front_ = rear_ = 1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceEnd()); 1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emergency_stack_ = NULL; 1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PromotionQueue::RelocateQueueHead() { 1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(emergency_stack_ == NULL); 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Page* p = Page::FromAllocationTop(reinterpret_cast<Address>(rear_)); 1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t* head_start = rear_; 1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t* head_end = Min(front_, reinterpret_cast<intptr_t*>(p->area_end())); 1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int entries_count = 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(head_end - head_start) / kEntrySizeInWords; 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emergency_stack_ = new List<Entry>(2 * entries_count); 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (head_start != head_end) { 1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = static_cast<int>(*(head_start++)); 1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj = reinterpret_cast<HeapObject*>(*(head_start++)); 1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emergency_stack_->Add(Entry(obj, size)); 1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rear_ = head_end; 1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ScavengeWeakObjectRetainer : public WeakObjectRetainer { 1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit ScavengeWeakObjectRetainer(Heap* heap) : heap_(heap) {} 1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual Object* RetainAs(Object* object) { 1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!heap_->InFromSpace(object)) { 1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object; 1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord map_word = HeapObject::cast(object)->map_word(); 1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map_word.IsForwardingAddress()) { 1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return map_word.ToForwardingAddress(); 1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::Scavenge() { 1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocationLock relocation_lock(this); 1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_heap) VerifyNonPointerSpacePointers(this); 1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_state_ = SCAVENGE; 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Implements Cheney's copying algorithm 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG(isolate_, ResourceEvent("scavenge", "begin")); 1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clear descriptor cache. 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->descriptor_lookup_cache()->Clear(); 1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Used for updating survived_since_last_expansion_ at function end. 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); 1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SelectScavengingVisitorsTable(); 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->PrepareForScavenge(); 1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Flip the semispaces. After flipping, to space is empty, from space has 1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // live objects. 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.Flip(); 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.ResetAllocationInfo(); 1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We need to sweep newly copied objects which can be either in the 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to space or promoted to the old generation. For to-space 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // objects, we treat the bottom of the to space as a queue. Newly 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // copied and unswept objects lie between a 'front' mark and the 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocation pointer. 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Promoted objects can go into various old-generation spaces, and 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // can be allocated internally in the spaces (from the free list). 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We treat the top of the to space as a queue of addresses of 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // promoted objects. The addresses of newly promoted and unswept 1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // objects lie between a 'front' mark and a 'rear' mark that is 1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // updated as a side effect of promoting an object. 1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There is guaranteed to be enough room at the top of the to space 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for the addresses of promoted objects: every object promoted 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // frees up its size in bytes from the top of the new space, and 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // objects are at least one pointer in size. 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address new_space_front = new_space_.ToSpaceStart(); 1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch promotion_queue_.Initialize(); 1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer()->Clean(); 1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScavengeVisitor scavenge_visitor(this); 1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy roots. 1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); 1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy objects reachable from the old generation. 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreBufferRebuildScope scope(this, store_buffer(), 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ScavengeStoreBufferCallback); 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer()->IteratePointersToNewSpace(&ScavengeObject); 1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy objects reachable from simple cells by scavenging cell values 1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // directly. 1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectIterator cell_iterator(cell_space_); 1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HeapObject* heap_object = cell_iterator.Next(); heap_object != NULL; 1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_object = cell_iterator.Next()) { 1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (heap_object->IsCell()) { 1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cell* cell = Cell::cast(heap_object); 1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address value_address = cell->ValueAddress(); 1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); 1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy objects reachable from global property cells by scavenging global 1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // property cell values directly. 1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectIterator js_global_property_cell_iterator(property_cell_space_); 1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HeapObject* heap_object = js_global_property_cell_iterator.Next(); 1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_object != NULL; 1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_object = js_global_property_cell_iterator.Next()) { 1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (heap_object->IsPropertyCell()) { 1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyCell* cell = PropertyCell::cast(heap_object); 1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address value_address = cell->ValueAddress(); 1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address type_address = cell->TypeAddress(); 1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(type_address)); 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy objects reachable from the encountered weak collections list. 1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenge_visitor.VisitPointer(&encountered_weak_collections_); 1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy objects reachable from the code flushing candidates list. 1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkCompactCollector* collector = mark_compact_collector(); 1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (collector->is_code_flushing_enabled()) { 1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor); 1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_front = DoScavenge(&scavenge_visitor, new_space_front); 1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (isolate()->global_handles()->IterateObjectGroups( 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &scavenge_visitor, &IsUnscavengedHeapObject)) { 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_front = DoScavenge(&scavenge_visitor, new_space_front); 1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->global_handles()->RemoveObjectGroups(); 1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->global_handles()->RemoveImplicitRefGroups(); 1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( 1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &IsUnscavengedHeapObject); 1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( 1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &scavenge_visitor); 1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_front = DoScavenge(&scavenge_visitor, new_space_front); 1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateNewSpaceReferencesInExternalStringTable( 1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &UpdateNewSpaceReferenceInExternalStringTableEntry); 1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch promotion_queue_.Destroy(); 1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->UpdateMarkingDequeAfterScavenge(); 1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScavengeWeakObjectRetainer weak_object_retainer(this); 1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessWeakReferences(&weak_object_retainer); 1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(new_space_front == new_space_.top()); 1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set age mark. 1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.set_age_mark(new_space_.top()); 1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.LowerInlineAllocationLimit( 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.inline_allocation_limit_step()); 1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update how much has survived scavenge. 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementYoungSurvivorsCounter(static_cast<int>( 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG(isolate_, ResourceEvent("scavenge", "end")); 1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_state_ = NOT_IN_GC; 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_idle_time_handler_.NotifyScavenge(); 1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochString* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** p) { 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord first_word = HeapObject::cast(*p)->map_word(); 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!first_word.IsForwardingAddress()) { 1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unreachable external string can be finalized. 1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->FinalizeExternalString(String::cast(*p)); 1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // String is still reachable. 1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return String::cast(first_word.ToForwardingAddress()); 1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateNewSpaceReferencesInExternalStringTable( 1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalStringTableUpdaterCallback updater_func) { 1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_heap) { 1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_string_table_.Verify(); 1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (external_string_table_.new_space_strings_.is_empty()) return; 1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** start = &external_string_table_.new_space_strings_[0]; 1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** end = start + external_string_table_.new_space_strings_.length(); 1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** last = start; 1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; p < end; ++p) { 1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(InFromSpace(*p)); 1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String* target = updater_func(this, p); 1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target == NULL) continue; 1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(target->IsExternalString()); 1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (InNewSpace(target)) { 1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // String is still in new space. Update the table entry. 1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *last = target; 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++last; 1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // String got promoted. Move it to the old string list. 1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_string_table_.AddOldString(target); 1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(last <= end); 1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_string_table_.ShrinkNewStrings(static_cast<int>(last - start)); 1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateReferencesInExternalStringTable( 1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalStringTableUpdaterCallback updater_func) { 1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update old space string references. 1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (external_string_table_.old_space_strings_.length() > 0) { 1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** start = &external_string_table_.old_space_strings_[0]; 1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** end = start + external_string_table_.old_space_strings_.length(); 1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; p < end; ++p) *p = updater_func(this, p); 1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateNewSpaceReferencesInExternalStringTable(updater_func); 1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { 1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessArrayBuffers(retainer); 1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessNativeContexts(retainer); 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(mvstanton): AllocationSites only need to be processed during 1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MARK_COMPACT, as they live in old space. Verify and address. 1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessAllocationSites(retainer); 1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) { 1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* head = VisitWeakList<Context>(this, native_contexts_list(), retainer); 1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update the head of the list of contexts. 1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_native_contexts_list(head); 1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer) { 1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* array_buffer_obj = 1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitWeakList<JSArrayBuffer>(this, array_buffers_list(), retainer); 1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_array_buffers_list(array_buffer_obj); 1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TearDownArrayBuffers() { 1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* undefined = undefined_value(); 1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object* o = array_buffers_list(); o != undefined;) { 1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSArrayBuffer* buffer = JSArrayBuffer::cast(o); 1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FreeArrayBuffer(isolate(), buffer); 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch o = buffer->weak_next(); 1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_array_buffers_list(undefined); 1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) { 1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* allocation_site_obj = 1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitWeakList<AllocationSite>(this, allocation_sites_list(), retainer); 1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_allocation_sites_list(allocation_site_obj); 1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) { 1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation_scope; 1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* cur = allocation_sites_list(); 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool marked = false; 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (cur->IsAllocationSite()) { 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite* casted = AllocationSite::cast(cur); 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (casted->GetPretenureMode() == flag) { 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch casted->ResetPretenureDecision(); 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch casted->set_deopt_dependent_code(true); 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch marked = true; 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cur = casted->weak_next(); 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (marked) isolate_->stack_guard()->RequestDeoptMarkedAllocationSites(); 1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EvaluateOldSpaceLocalPretenuring( 1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t size_of_objects_before_gc) { 1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t size_of_objects_after_gc = SizeOfObjects(); 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double old_generation_survival_rate = 1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (static_cast<double>(size_of_objects_after_gc) * 100) / 1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<double>(size_of_objects_before_gc); 1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (old_generation_survival_rate < kOldSurvivalRateLowThreshold) { 1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Too many objects died in the old generation, pretenuring of wrong 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocation sites may be the cause for that. We have to deopt all 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // dependent code registered in the allocation sites to re-evaluate 1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // our pretenuring decisions. 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ResetAllAllocationSitesDependentCode(TENURED); 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_pretenuring) { 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF( 1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "Deopt all allocation sites dependent code due to low survival " 1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "rate in the old generation %f\n", 1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_generation_survival_rate); 1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { 1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation; 1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All external strings are listed in the external string table. 1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class ExternalStringTableVisitorAdapter : public ObjectVisitor { 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit ExternalStringTableVisitorAdapter( 1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ExternalResourceVisitor* visitor) 1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : visitor_(visitor) {} 1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void VisitPointers(Object** start, Object** end) { 1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; p < end; p++) { 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((*p)->IsExternalString()); 1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor_->VisitExternalString( 1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Utils::ToLocal(Handle<String>(String::cast(*p)))); 1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ExternalResourceVisitor* visitor_; 1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } external_string_table_visitor(visitor); 1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_string_table_.Iterate(&external_string_table_visitor); 1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> { 1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void VisitPointer(Heap* heap, Object** p) { 1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* object = *p; 1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!heap->InNewSpace(object)) return; 1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), 1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<HeapObject*>(object)); 1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Heap::DoScavenge(ObjectVisitor* scavenge_visitor, 1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address new_space_front) { 1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { 1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SemiSpace::AssertValidRange(new_space_front, new_space_.top()); 1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The addresses new_space_front and new_space_.top() define a 1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // queue of unprocessed copied objects. Process them until the 1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // queue is empty. 1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (new_space_front != new_space_.top()) { 1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!NewSpacePage::IsAtEnd(new_space_front)) { 1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object = HeapObject::FromAddress(new_space_front); 1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_front += 1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NewSpaceScavenger::IterateBody(object->map(), object); 1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_front = 1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NewSpacePage::FromLimit(new_space_front)->next_page()->area_start(); 1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Promote and process all the to-be-promoted objects. 1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreBufferRebuildScope scope(this, store_buffer(), 1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ScavengeStoreBufferCallback); 1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!promotion_queue()->is_empty()) { 1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* target; 1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size; 1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch promotion_queue()->remove(&target, &size); 1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Promoted object might be already partially visited 1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // during old space pointer iteration. Thus we search specificly 1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for pointers to from semispace instead of looking for pointers 1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to new space. 1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!target->IsMap()); 1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterateAndMarkPointersToFromSpace( 1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target->address(), target->address() + size, &ScavengeObject); 1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Take another spin if there are now unswept objects in new space 1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (there are currently no more unswept promoted objects). 1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (new_space_front != new_space_.top()); 1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_space_front; 1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSTATIC_ASSERT((FixedDoubleArray::kHeaderSize & kDoubleAlignmentMask) == 1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0); // NOLINT 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSTATIC_ASSERT((ConstantPoolArray::kFirstEntryOffset & kDoubleAlignmentMask) == 1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0); // NOLINT 1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSTATIC_ASSERT((ConstantPoolArray::kExtendedFirstOffset & 1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kDoubleAlignmentMask) == 0); // NOLINT 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINLINE(static HeapObject* EnsureDoubleAligned(Heap* heap, HeapObject* object, 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size)); 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic HeapObject* EnsureDoubleAligned(Heap* heap, HeapObject* object, 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size) { 1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((OffsetFrom(object->address()) & kDoubleAlignmentMask) != 0) { 1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CreateFillerObjectAt(object->address(), kPointerSize); 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return HeapObject::FromAddress(object->address() + kPointerSize); 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CreateFillerObjectAt(object->address() + size - kPointerSize, 1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kPointerSize); 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object; 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum LoggingAndProfiling { 1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOGGING_AND_PROFILING_ENABLED, 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOGGING_AND_PROFILING_DISABLED 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS }; 1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <MarksHandling marks_handling, 1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoggingAndProfiling logging_and_profiling_mode> 1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ScavengingVisitor : public StaticVisitorBase { 1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Initialize() { 1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString); 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); 1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitByteArray, &EvacuateByteArray); 1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitFixedArray, &EvacuateFixedArray); 1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); 1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitFixedTypedArray, &EvacuateFixedTypedArray); 1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitFixedFloat64Array, &EvacuateFixedFloat64Array); 1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register( 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitNativeContext, 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Context::kSize>); 1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register( 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitConsString, 1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< 1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConsString::kSize>); 1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register( 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitSlicedString, 1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< 1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlicedString::kSize>); 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register( 1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitSymbol, 1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< 1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Symbol::kSize>); 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register( 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitSharedFunctionInfo, 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< 1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo::kSize>); 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitJSWeakCollection, 1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitJSArrayBuffer, 1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); 1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitJSTypedArray, 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); 1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitJSDataView, 1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); 1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitJSRegExp, 1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); 1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (marks_handling == IGNORE_MARKS) { 1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register( 1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitJSFunction, 1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< 1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction::kSize>); 1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.Register(kVisitJSFunction, &EvacuateJSFunction); 1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>, 1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitDataObject, kVisitDataObjectGeneric>(); 1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, 1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitJSObject, kVisitJSObjectGeneric>(); 1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, 1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVisitStruct, kVisitStructGeneric>(); 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static VisitorDispatchTable<ScavengingCallback>* GetTable() { 1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return &table_; 1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum ObjectContents { DATA_OBJECT, POINTER_OBJECT }; 1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void RecordCopiedObject(Heap* heap, HeapObject* obj) { 1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool should_record = false; 1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch should_record = FLAG_heap_stats; 1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch should_record = should_record || FLAG_log_gc; 1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (should_record) { 1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (heap->new_space()->Contains(obj)) { 1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->new_space()->RecordAllocation(obj); 1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->new_space()->RecordPromotion(obj); 1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Helper function used by CopyObject to copy a source object to an 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocated target object and update the forwarding pointer in the source 1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object. Returns the target object. 1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static void MigrateObject(Heap* heap, HeapObject* source, 1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* target, int size)) { 1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we migrate into to-space, then the to-space top pointer should be 1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // right after the target object. Incorporate double alignment 1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // over-allocation. 1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!heap->InToSpace(target) || 1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target->address() + size == heap->new_space()->top() || 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target->address() + size + kPointerSize == heap->new_space()->top()); 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure that we do not overwrite the promotion queue which is at 1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the end of to-space. 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!heap->InToSpace(target) || 1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->promotion_queue()->IsBelowPromotionQueue( 1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->new_space()->top())); 1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the content of source to target. 1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CopyBlock(target->address(), source->address(), size); 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set the forwarding address. 1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch source->set_map_word(MapWord::FromForwardingAddress(target)); 1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) { 1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update NewSpace stats if necessary. 1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordCopiedObject(heap, target); 1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->OnMoveEvent(target, source, size); 1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (marks_handling == TRANSFER_MARKS) { 1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Marking::TransferColor(source, target)) { 1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::IncrementLiveBytesFromGC(target->address(), size); 1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <int alignment> 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline bool SemiSpaceCopyObject(Map* map, HeapObject** slot, 1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object, int object_size) { 1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = map->GetHeap(); 1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int allocation_size = object_size; 1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (alignment != kObjectAlignment) { 1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(alignment == kDoubleAlignment); 1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_size += kPointerSize; 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(heap->AllowedToBeMigrated(object, NEW_SPACE)); 1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->new_space()->AllocateRaw(allocation_size); 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* target = NULL; // Initialization to please compiler. 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation.To(&target)) { 1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Order is important here: Set the promotion limit before storing a 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // filler for double alignment or migrating the object. Otherwise we 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // may end up overwriting promotion queue entries when we migrate the 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object. 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); 1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (alignment != kObjectAlignment) { 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target = EnsureDoubleAligned(heap, target, allocation_size); 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Order is important: slot might be inside of the target if target 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // was allocated over a dead object and slot comes from the store 1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // buffer. 1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *slot = target; 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MigrateObject(heap, object, target, object_size); 1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->IncrementSemiSpaceCopiedObjectSize(object_size); 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <ObjectContents object_contents, int alignment> 1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline bool PromoteObject(Map* map, HeapObject** slot, 1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object, int object_size) { 1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = map->GetHeap(); 1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int allocation_size = object_size; 1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (alignment != kObjectAlignment) { 1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(alignment == kDoubleAlignment); 1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_size += kPointerSize; 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation; 2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object_contents == DATA_OBJECT) { 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(heap->AllowedToBeMigrated(object, OLD_DATA_SPACE)); 2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = heap->old_data_space()->AllocateRaw(allocation_size); 2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(heap->AllowedToBeMigrated(object, OLD_POINTER_SPACE)); 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = heap->old_pointer_space()->AllocateRaw(allocation_size); 2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* target = NULL; // Initialization to please compiler. 2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation.To(&target)) { 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (alignment != kObjectAlignment) { 2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target = EnsureDoubleAligned(heap, target, allocation_size); 2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Order is important: slot might be inside of the target if target 2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // was allocated over a dead object and slot comes from the store 2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // buffer. 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *slot = target; 2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MigrateObject(heap, object, target, object_size); 2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object_contents == POINTER_OBJECT) { 2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map->instance_type() == JS_FUNCTION_TYPE) { 2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->promotion_queue()->insert(target, 2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction::kNonWeakFieldsEndOffset); 2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->promotion_queue()->insert(target, object_size); 2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->IncrementPromotedObjectsSize(object_size); 2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <ObjectContents object_contents, int alignment> 2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateObject(Map* map, HeapObject** slot, 2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object, int object_size) { 2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(object->Size() == object_size); 2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = map->GetHeap(); 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!heap->ShouldBePromoted(object->address(), object_size)) { 2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A semi-space copy may fail due to fragmentation. In that case, we 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // try to promote the object. 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (PromoteObject<object_contents, alignment>(map, slot, object, 2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size)) { 2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If promotion failed, we try to copy the object to the other semi-space 2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) return; 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateJSFunction(Map* map, HeapObject** slot, 2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction::kSize>(map, slot, object); 2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord map_word = object->map_word(); 2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(map_word.IsForwardingAddress()); 2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* target = map_word.ToForwardingAddress(); 2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit mark_bit = Marking::MarkBitFrom(target); 2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Marking::IsBlack(mark_bit)) { 2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This object is black and it might not be rescanned by marker. 2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We should explicitly record code entry slot for compaction because 2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // promotion queue processing (IterateAndMarkPointersToFromSpace) will 2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // miss it as it is not HeapObject-tagged. 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address code_entry_slot = 2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target->address() + JSFunction::kCodeEntryOffset; 2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot)); 2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot( 2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_entry_slot, code); 2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateFixedArray(Map* map, HeapObject** slot, 2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); 2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<POINTER_OBJECT, kObjectAlignment>(map, slot, object, 2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateFixedDoubleArray(Map* map, HeapObject** slot, 2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); 2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = FixedDoubleArray::SizeFor(length); 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<DATA_OBJECT, kDoubleAlignment>(map, slot, object, 2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateFixedTypedArray(Map* map, HeapObject** slot, 2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size(); 2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object, 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, 2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); 2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<DATA_OBJECT, kDoubleAlignment>(map, slot, object, 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateByteArray(Map* map, HeapObject** slot, 2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object, 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = SeqOneByteString::cast(object) 2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->SeqOneByteStringSize(map->instance_type()); 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object, 2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateSeqTwoByteString(Map* map, HeapObject** slot, 2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = SeqTwoByteString::cast(object) 2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->SeqTwoByteStringSize(map->instance_type()); 2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object, 2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void EvacuateShortcutCandidate(Map* map, HeapObject** slot, 2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsShortcutCandidate(map->instance_type())); 2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = map->GetHeap(); 2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (marks_handling == IGNORE_MARKS && 2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConsString::cast(object)->unchecked_second() == heap->empty_string()) { 2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* first = 2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject::cast(ConsString::cast(object)->unchecked_first()); 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *slot = first; 2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!heap->InNewSpace(first)) { 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->set_map_word(MapWord::FromForwardingAddress(first)); 2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord first_word = first->map_word(); 2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (first_word.IsForwardingAddress()) { 2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* target = first_word.ToForwardingAddress(); 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *slot = target; 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->set_map_word(MapWord::FromForwardingAddress(target)); 2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->DoScavengeObject(first->map(), slot, first); 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->set_map_word(MapWord::FromForwardingAddress(*slot)); 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = ConsString::kSize; 2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<POINTER_OBJECT, kObjectAlignment>(map, slot, object, 2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <ObjectContents object_contents> 2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class ObjectEvacuationStrategy { 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <int object_size> 2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void VisitSpecialized(Map* map, HeapObject** slot, 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object) { 2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<object_contents, kObjectAlignment>(map, slot, object, 2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline void Visit(Map* map, HeapObject** slot, HeapObject* object) { 2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = map->instance_size(); 2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EvacuateObject<object_contents, kObjectAlignment>(map, slot, object, 2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_size); 2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static VisitorDispatchTable<ScavengingCallback> table_; 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <MarksHandling marks_handling, 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoggingAndProfiling logging_and_profiling_mode> 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVisitorDispatchTable<ScavengingCallback> 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScavengingVisitor<marks_handling, logging_and_profiling_mode>::table_; 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void InitializeScavengingVisitorsTables() { 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScavengingVisitor<TRANSFER_MARKS, 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOGGING_AND_PROFILING_DISABLED>::Initialize(); 2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::Initialize(); 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScavengingVisitor<TRANSFER_MARKS, 2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOGGING_AND_PROFILING_ENABLED>::Initialize(); 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize(); 2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::SelectScavengingVisitorsTable() { 2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool logging_and_profiling = 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_verify_predictable || isolate()->logger()->is_logging() || 2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->cpu_profiler()->is_profiling() || 2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (isolate()->heap_profiler() != NULL && 2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->heap_profiler()->is_tracking_object_moves()); 2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!incremental_marking()->IsMarking()) { 2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!logging_and_profiling) { 2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenging_visitors_table_.CopyFrom(ScavengingVisitor< 2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::GetTable()); 2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenging_visitors_table_.CopyFrom(ScavengingVisitor< 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::GetTable()); 2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!logging_and_profiling) { 2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenging_visitors_table_.CopyFrom(ScavengingVisitor< 2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TRANSFER_MARKS, LOGGING_AND_PROFILING_DISABLED>::GetTable()); 2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenging_visitors_table_.CopyFrom(ScavengingVisitor< 2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TRANSFER_MARKS, LOGGING_AND_PROFILING_ENABLED>::GetTable()); 2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (incremental_marking()->IsCompacting()) { 2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // When compacting forbid short-circuiting of cons-strings. 2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Scavenging code relies on the fact that new space object 2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // can't be evacuated into evacuation candidate but 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // short-circuiting violates this assumption. 2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenging_visitors_table_.Register( 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitorBase::kVisitShortcutCandidate, 2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scavenging_visitors_table_.GetVisitorById( 2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitorBase::kVisitConsString)); 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(object->GetIsolate()->heap()->InFromSpace(object)); 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord first_word = object->map_word(); 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(!first_word.IsForwardingAddress()); 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map = first_word.ToMap(); 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->GetHeap()->DoScavengeObject(map, p, object); 2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocatePartialMap(InstanceType instance_type, 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int instance_size) { 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* result; 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE); 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Map::cast cannot be used due to uninitialized map field. 2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map()); 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_instance_type(instance_type); 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_instance_size(instance_size); 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_visitor_id( 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitorBase::GetVisitorId(instance_type, instance_size)); 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_inobject_properties(0); 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_pre_allocated_property_fields(0); 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_unused_property_fields(0); 2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_bit_field(0); 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_bit_field2(0); 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map::OwnsDescriptors::encode(true); 2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3); 2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateMap(InstanceType instance_type, 2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int instance_size, 2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind) { 2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE); 2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(meta_map()); 2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map = Map::cast(result); 2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_instance_type(instance_type); 2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_visitor_id( 2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitorBase::GetVisitorId(instance_type, instance_size)); 2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_prototype(null_value(), SKIP_WRITE_BARRIER); 2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_constructor(null_value(), SKIP_WRITE_BARRIER); 2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_instance_size(instance_size); 2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_inobject_properties(0); 2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_pre_allocated_property_fields(0); 2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER); 2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_dependent_code(DependentCode::cast(empty_fixed_array()), 2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SKIP_WRITE_BARRIER); 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->init_back_pointer(undefined_value()); 2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_unused_property_fields(0); 2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_instance_descriptors(empty_descriptor_array()); 2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_bit_field(0); 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_bit_field2(1 << Map::kIsExtensible); 2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map::OwnsDescriptors::encode(true); 2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_bit_field3(bit_field3); 2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->set_elements_kind(elements_kind); 2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return map; 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFillerObject(int size, bool double_align, 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space) { 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj; 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, space); 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return allocation; 2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(chunk->owner()->identity() == space); 2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateFillerObjectAt(obj->address(), size); 2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return obj; 2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Heap::StringTypeTable Heap::string_type_table[] = { 2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ 2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { type, size, k##camel_name##MapRootIndex } \ 2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch , 2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STRING_TYPE_LIST(STRING_TYPE_ELEMENT) 2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef STRING_TYPE_ELEMENT 2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Heap::ConstantStringTable Heap::constant_string_table[] = { 2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CONSTANT_STRING_ELEMENT(name, contents) \ 2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { contents, k##name##RootIndex } \ 2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch , 2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT) 2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef CONSTANT_STRING_ELEMENT 2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Heap::StructTable Heap::struct_table[] = { 2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define STRUCT_TABLE_ELEMENT(NAME, Name, name) \ 2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex } \ 2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch , 2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STRUCT_LIST(STRUCT_TABLE_ELEMENT) 2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef STRUCT_TABLE_ELEMENT 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CreateInitialMaps() { 2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj; 2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize); 2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return false; 2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Map::cast cannot be used due to uninitialized map field. 2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* new_meta_map = reinterpret_cast<Map*>(obj); 2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_meta_map(new_meta_map); 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_meta_map->set_map(new_meta_map); 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { // Partial map allocation 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name) \ 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { \ 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map; \ 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocatePartialMap((instance_type), (size)).To(&map)) return false; \ 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_##field_name##_map(map); \ 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array); 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined); 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null); 2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_PARTIAL_MAP(CONSTANT_POOL_ARRAY_TYPE, kVariableSizeSentinel, 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool_array); 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_PARTIAL_MAP 2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the empty array. 2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateEmptyFixedArray(); 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return false; 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_empty_fixed_array(FixedArray::cast(obj)); 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = Allocate(null_map(), OLD_POINTER_SPACE); 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return false; 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_null_value(Oddball::cast(obj)); 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Oddball::cast(obj)->set_kind(Oddball::kNull); 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = Allocate(undefined_map(), OLD_POINTER_SPACE); 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return false; 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_undefined_value(Oddball::cast(obj)); 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Oddball::cast(obj)->set_kind(Oddball::kUndefined); 2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!InNewSpace(undefined_value())); 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set preliminary exception sentinel value before actually initializing it. 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_exception(null_value()); 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the empty descriptor array. 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateEmptyFixedArray(); 2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return false; 2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_empty_descriptor_array(DescriptorArray::cast(obj)); 2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the constant pool array. 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateEmptyConstantPoolArray(); 2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return false; 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_empty_constant_pool_array(ConstantPoolArray::cast(obj)); 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fix the instance_descriptors for the existing maps. 2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch meta_map()->set_code_cache(empty_fixed_array()); 2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch meta_map()->set_dependent_code(DependentCode::cast(empty_fixed_array())); 2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch meta_map()->init_back_pointer(undefined_value()); 2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch meta_map()->set_instance_descriptors(empty_descriptor_array()); 2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fixed_array_map()->set_code_cache(empty_fixed_array()); 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fixed_array_map()->set_dependent_code( 2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DependentCode::cast(empty_fixed_array())); 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fixed_array_map()->init_back_pointer(undefined_value()); 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fixed_array_map()->set_instance_descriptors(empty_descriptor_array()); 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undefined_map()->set_code_cache(empty_fixed_array()); 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undefined_map()->set_dependent_code(DependentCode::cast(empty_fixed_array())); 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undefined_map()->init_back_pointer(undefined_value()); 2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undefined_map()->set_instance_descriptors(empty_descriptor_array()); 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch null_map()->set_code_cache(empty_fixed_array()); 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch null_map()->set_dependent_code(DependentCode::cast(empty_fixed_array())); 2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch null_map()->init_back_pointer(undefined_value()); 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch null_map()->set_instance_descriptors(empty_descriptor_array()); 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool_array_map()->set_code_cache(empty_fixed_array()); 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool_array_map()->set_dependent_code( 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DependentCode::cast(empty_fixed_array())); 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool_array_map()->init_back_pointer(undefined_value()); 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool_array_map()->set_instance_descriptors(empty_descriptor_array()); 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fix prototype object for existing maps. 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch meta_map()->set_prototype(null_value()); 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch meta_map()->set_constructor(null_value()); 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fixed_array_map()->set_prototype(null_value()); 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fixed_array_map()->set_constructor(null_value()); 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undefined_map()->set_prototype(null_value()); 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undefined_map()->set_constructor(null_value()); 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch null_map()->set_prototype(null_value()); 2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch null_map()->set_constructor(null_value()); 2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool_array_map()->set_prototype(null_value()); 2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool_array_map()->set_constructor(null_value()); 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { // Map allocation 2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_MAP(instance_type, size, field_name) \ 2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { \ 2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map; \ 2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocateMap((instance_type), size).To(&map)) return false; \ 2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_##field_name##_map(map); \ 2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \ 2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name) 2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, fixed_cow_array) 2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fixed_array_map() != fixed_cow_array_map()); 2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info) 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number) 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize, 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mutable_heap_number) 2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol) 2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign) 2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole); 2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean); 2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized); 2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker); 2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, no_interceptor_result_sentinel); 2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception); 2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception); 2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned i = 0; i < arraysize(string_type_table); i++) { 2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const StringTypeTable& entry = string_type_table[i]; 2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateMap(entry.type, entry.size); 2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return false; 2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark cons string maps as unstable, because their objects can change 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // maps during GC. 2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map = Map::cast(obj); 2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (StringShape(entry.type).IsCons()) map->mark_unstable(); 2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch roots_[entry.index] = map; 2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(STRING_TYPE, undetectable_string) 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undetectable_string_map()->set_is_undetectable(); 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(ONE_BYTE_STRING_TYPE, undetectable_one_byte_string); 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undetectable_one_byte_string_map()->set_is_undetectable(); 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_DOUBLE_ARRAY_TYPE, fixed_double_array) 2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(BYTE_ARRAY_TYPE, byte_array) 2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FREE_SPACE_TYPE, free_space) 2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_EXTERNAL_ARRAY_MAP(Type, type, TYPE, ctype, size) \ 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(EXTERNAL_##TYPE##_ARRAY_TYPE, ExternalArray::kAlignedSize, \ 2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_##type##_array) 2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(ALLOCATE_EXTERNAL_ARRAY_MAP) 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_EXTERNAL_ARRAY_MAP 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_FIXED_TYPED_ARRAY_MAP(Type, type, TYPE, ctype, size) \ 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_##TYPE##_ARRAY_TYPE, fixed_##type##_array) 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(ALLOCATE_FIXED_TYPED_ARRAY_MAP) 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_FIXED_TYPED_ARRAY_MAP 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements) 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(CODE_TYPE, code) 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell) 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell) 2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler) 2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler) 2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned i = 0; i < arraysize(struct_table); i++) { 2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const StructTable& entry = struct_table[i]; 2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map; 2556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocateMap(entry.type, entry.size).To(&map)) return false; 2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch roots_[entry.index] = map; 2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, hash_table) 2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, ordered_hash_table) 2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context) 2564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context) 2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, with_context) 2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, block_context) 2567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_context) 2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, global_context) 2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, native_context) 2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch native_context_map()->set_dictionary_map(true); 2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch native_context_map()->set_visitor_id( 2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitorBase::kVisitNativeContext); 2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kAlignedSize, 2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_function_info) 2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kSize, message_object) 2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, external) 2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_map()->set_is_extensible(false); 2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_VARSIZE_MAP 2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_MAP 2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { // Empty arrays 2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ByteArray* byte_array; 2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false; 2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_empty_byte_array(byte_array); 2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_EMPTY_EXTERNAL_ARRAY(Type, type, TYPE, ctype, size) \ 2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { \ 2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArray* obj; \ 2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocateEmptyExternalArray(kExternal##Type##Array).To(&obj)) \ 2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; \ 2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_empty_external_##type##_array(obj); \ 2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(ALLOCATE_EMPTY_EXTERNAL_ARRAY) 2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_EMPTY_EXTERNAL_ARRAY 2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \ 2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { \ 2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedTypedArrayBase* obj; \ 2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array).To(&obj)) \ 2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; \ 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_empty_fixed_##type##_array(obj); \ 2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(ALLOCATE_EMPTY_FIXED_TYPED_ARRAY) 2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_EMPTY_FIXED_TYPED_ARRAY 2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!InNewSpace(empty_fixed_array())); 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateHeapNumber(double value, MutableMode mode, 2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure) { 2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Statically ensure that it is safe to allocate heap numbers in paged 2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // spaces. 2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = HeapNumber::kSize; 2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxRegularHeapObjectSize); 2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); 2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map = mode == MUTABLE ? mutable_heap_number_map() : heap_number_map(); 2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject::cast(result)->set_map_no_write_barrier(map); 2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapNumber::cast(result)->set_value(value); 2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateCell(Object* value) { 2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = Cell::kSize; 2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(Cell::kSize <= Page::kMaxRegularHeapObjectSize); 2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, CELL_SPACE, CELL_SPACE); 2648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(cell_map()); 2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cell::cast(result)->set_value(value); 2652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocatePropertyCell() { 2657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = PropertyCell::kSize; 2658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(PropertyCell::kSize <= Page::kMaxRegularHeapObjectSize); 2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 2662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRaw(size, PROPERTY_CELL_SPACE, PROPERTY_CELL_SPACE); 2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(global_property_cell_map()); 2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyCell* cell = PropertyCell::cast(result); 2667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell->set_dependent_code(DependentCode::cast(empty_fixed_array()), 2668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SKIP_WRITE_BARRIER); 2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell->set_value(the_hole_value()); 2670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell->set_type(HeapType::None()); 2671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateApiObjects() { 2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate()); 2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> new_neander_map = 2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't use Smi-only elements optimizations for objects with the neander 2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // map. There are too many cases where element values are set directly with a 2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bottleneck to trap the Smi-only -> fast elements transition, and there 2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // appears to be no benefit for optimize this case. 2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_neander_map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND); 2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_neander_map(*new_neander_map); 2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> listeners = factory->NewNeanderObject(); 2689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> elements = factory->NewFixedArray(2); 2690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->set(0, Smi::FromInt(0)); 2691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch listeners->set_elements(*elements); 2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_message_listeners(*listeners); 2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateJSEntryStub() { 2697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSEntryStub stub(isolate(), StackFrame::ENTRY); 2698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_js_entry_code(*stub.GetCode()); 2699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateJSConstructEntryStub() { 2703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSEntryStub stub(isolate(), StackFrame::ENTRY_CONSTRUCT); 2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_js_construct_entry_code(*stub.GetCode()); 2705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateFixedStubs() { 2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Here we create roots for fixed stubs. They are needed at GC 2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for cooking and uncooking (check out frames.cc). 2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The eliminates the need for doing dictionary lookup in the 2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stub cache for these stubs. 2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate()); 2714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create stubs that should be there, so we don't unexpectedly have to 2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // create them if we need them during the creation of another stub. 2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stub creation mixes raw pointers and handles in an unsafe manner so 2718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we cannot create stubs while we are creating stubs. 2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeStub::GenerateStubsAheadOfTime(isolate()); 2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MacroAssembler::Abort calls (usually enabled with --debug-code) depend on 2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // CEntryStub, so we need to call GenerateStubsAheadOfTime before JSEntryStub 2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is created. 2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // gcc-4.4 has problem generating correct code of following snippet: 2726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // { JSEntryStub stub; 2727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // js_entry_code_ = *stub.GetCode(); 2728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // } 2729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // { JSConstructEntryStub stub; 2730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // js_construct_entry_code_ = *stub.GetCode(); 2731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // } 2732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // To workaround the problem, make separate functions without inlining. 2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::CreateJSEntryStub(); 2734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::CreateJSConstructEntryStub(); 2735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateInitialObjects() { 2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate()); 2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 2741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The -0 value must be set before NewNumber works. 2743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_minus_zero_value(*factory->NewHeapNumber(-0.0, IMMUTABLE, TENURED)); 2744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(std::signbit(minus_zero_value()->Number()) != 0); 2745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_nan_value( 2747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *factory->NewHeapNumber(base::OS::nan_value(), IMMUTABLE, TENURED)); 2748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, IMMUTABLE, TENURED)); 2749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The hole has not been created yet, but we want to put something 2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // predictable in the gaps in the string table, so lets make that Smi zero. 2752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_the_hole_value(reinterpret_cast<Oddball*>(Smi::FromInt(0))); 2753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate initial string table. 2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_string_table(*StringTable::New(isolate(), kInitialStringTableSize)); 2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finish initializing oddballs after creating the string table. 2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Oddball::Initialize(isolate(), factory->undefined_value(), "undefined", 2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->nan_value(), Oddball::kUndefined); 2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the null_value. 2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Oddball::Initialize(isolate(), factory->null_value(), "null", 2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(Smi::FromInt(0), isolate()), Oddball::kNull); 2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_true_value(*factory->NewOddball(factory->boolean_map(), "true", 2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(Smi::FromInt(1), isolate()), 2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Oddball::kTrue)); 2768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_false_value(*factory->NewOddball(factory->boolean_map(), "false", 2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(Smi::FromInt(0), isolate()), 2771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Oddball::kFalse)); 2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_the_hole_value(*factory->NewOddball(factory->the_hole_map(), "hole", 2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(Smi::FromInt(-1), isolate()), 2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Oddball::kTheHole)); 2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_uninitialized_value(*factory->NewOddball( 2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->uninitialized_map(), "uninitialized", 2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(Smi::FromInt(-1), isolate()), Oddball::kUninitialized)); 2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_arguments_marker(*factory->NewOddball( 2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->arguments_marker_map(), "arguments_marker", 2783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(Smi::FromInt(-4), isolate()), Oddball::kArgumentMarker)); 2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_no_interceptor_result_sentinel(*factory->NewOddball( 2786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->no_interceptor_result_sentinel_map(), 2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "no_interceptor_result_sentinel", handle(Smi::FromInt(-2), isolate()), 2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Oddball::kOther)); 2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_termination_exception(*factory->NewOddball( 2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->termination_exception_map(), "termination_exception", 2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(Smi::FromInt(-3), isolate()), Oddball::kOther)); 2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_exception(*factory->NewOddball(factory->exception_map(), "exception", 2795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(Smi::FromInt(-5), isolate()), 2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Oddball::kException)); 2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned i = 0; i < arraysize(constant_string_table); i++) { 2799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> str = 2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->InternalizeUtf8String(constant_string_table[i].contents); 2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch roots_[constant_string_table[i].index] = *str; 2802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the hidden string which is used to identify the hidden properties 2805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in JSObjects. The hash code has a special value so that it will not match 2806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the empty string when searching for the property. It cannot be part of the 2807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // loop above because it needs to be allocated manually with the special 2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash code in place. The hash code for the hidden_string is zero to ensure 2809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that it will always be at the first entry in property descriptors. 2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hidden_string_ = *factory->NewOneByteInternalizedString( 2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OneByteVector("", 0), String::kEmptyStringHash); 2812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create the code_stubs dictionary. The initial size is set to avoid 2814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // expanding the dictionary during bootstrapping. 2815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_code_stubs(*UnseededNumberDictionary::New(isolate(), 128)); 2816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create the non_monomorphic_cache used in stub-cache.cc. The initial size 2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is set to avoid expanding the dictionary during bootstrapping. 2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_non_monomorphic_cache(*UnseededNumberDictionary::New(isolate(), 64)); 2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_polymorphic_code_cache(PolymorphicCodeCache::cast( 2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *factory->NewStruct(POLYMORPHIC_CODE_CACHE_TYPE))); 2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_instanceof_cache_function(Smi::FromInt(0)); 2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_instanceof_cache_map(Smi::FromInt(0)); 2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_instanceof_cache_answer(Smi::FromInt(0)); 2827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateFixedStubs(); 2829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the dictionary of intrinsic function names. 2831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<NameDictionary> intrinsic_names = 2832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionary::New(isolate(), Runtime::kNumFunctions, TENURED); 2833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::InitializeIntrinsicFunctionNames(isolate(), intrinsic_names); 2834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_intrinsic_function_names(*intrinsic_names); 2835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_number_string_cache( 2837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *factory->NewFixedArray(kInitialNumberStringCacheSize * 2, TENURED)); 2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate cache for single character one byte strings. 2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_single_character_string_cache( 2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *factory->NewFixedArray(String::kMaxOneByteCharCode + 1, TENURED)); 2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate cache for string split and regexp-multiple. 2844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_string_split_cache(*factory->NewFixedArray( 2845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegExpResultsCache::kRegExpResultsCacheSize, TENURED)); 2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_regexp_multiple_cache(*factory->NewFixedArray( 2847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegExpResultsCache::kRegExpResultsCacheSize, TENURED)); 2848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate cache for external strings pointing to native source code. 2850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_natives_source_cache( 2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *factory->NewFixedArray(Natives::GetBuiltinsCount())); 2852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_undefined_cell(*factory->NewCell(factory->undefined_value())); 2854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The symbol registry is initialized lazily. 2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_symbol_registry(undefined_value()); 2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate object to hold object observation state. 2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_observation_state(*factory->NewJSObjectFromMap( 2860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize))); 2861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Microtask queue uses the empty fixed array as a sentinel for "empty". 2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of queued microtasks stored in Isolate::pending_microtask_count(). 2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_microtask_queue(empty_fixed_array()); 2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_detailed_stack_trace_symbol(*factory->NewPrivateOwnSymbol()); 2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_elements_transition_symbol(*factory->NewPrivateOwnSymbol()); 2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_frozen_symbol(*factory->NewPrivateOwnSymbol()); 2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_megamorphic_symbol(*factory->NewPrivateOwnSymbol()); 2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_premonomorphic_symbol(*factory->NewPrivateOwnSymbol()); 2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_generic_symbol(*factory->NewPrivateOwnSymbol()); 2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_nonexistent_symbol(*factory->NewPrivateOwnSymbol()); 2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_normal_ic_symbol(*factory->NewPrivateOwnSymbol()); 2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_observed_symbol(*factory->NewPrivateOwnSymbol()); 2875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_stack_trace_symbol(*factory->NewPrivateOwnSymbol()); 2876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_uninitialized_symbol(*factory->NewPrivateOwnSymbol()); 2877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_home_object_symbol(*factory->NewPrivateOwnSymbol()); 2878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SeededNumberDictionary> slow_element_dictionary = 2880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SeededNumberDictionary::New(isolate(), 0, TENURED); 2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch slow_element_dictionary->set_requires_slow_elements(); 2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_empty_slow_element_dictionary(*slow_element_dictionary); 2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_materialized_objects(*factory->NewFixedArray(0, TENURED)); 2885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handling of script id generation is in Factory::NewScript. 2887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId)); 2888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_allocation_sites_scratchpad( 2890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *factory->NewFixedArray(kAllocationSiteScratchpadSize, TENURED)); 2891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeAllocationSitesScratchpad(); 2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize keyed lookup cache. 2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->keyed_lookup_cache()->Clear(); 2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize context slot cache. 2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->context_slot_cache()->Clear(); 2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize descriptor cache. 2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->descriptor_lookup_cache()->Clear(); 2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize compilation cache. 2903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->compilation_cache()->Clear(); 2904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) { 2908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RootListIndex writable_roots[] = { 2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStoreBufferTopRootIndex, 2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStackLimitRootIndex, 2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kNumberStringCacheRootIndex, 2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kInstanceofCacheFunctionRootIndex, 2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kInstanceofCacheMapRootIndex, 2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kInstanceofCacheAnswerRootIndex, 2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kCodeStubsRootIndex, 2916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kNonMonomorphicCacheRootIndex, 2917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kPolymorphicCodeCacheRootIndex, 2918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kLastScriptIdRootIndex, 2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kEmptyScriptRootIndex, 2920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kRealStackLimitRootIndex, 2921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kArgumentsAdaptorDeoptPCOffsetRootIndex, 2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kConstructStubDeoptPCOffsetRootIndex, 2923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kGetterStubDeoptPCOffsetRootIndex, 2924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kSetterStubDeoptPCOffsetRootIndex, 2925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStringTableRootIndex, 2926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 2927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned int i = 0; i < arraysize(writable_roots); i++) { 2929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_index == writable_roots[i]) return true; 2930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::RootCanBeTreatedAsConstant(RootListIndex root_index) { 2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !RootCanBeWrittenAfterInitialization(root_index) && 2937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !InNewSpace(roots_array_start()[root_index]); 2938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject* RegExpResultsCache::Lookup(Heap* heap, String* key_string, 2942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* key_pattern, ResultsCacheType type) { 2943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* cache; 2944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!key_string->IsInternalizedString()) return Smi::FromInt(0); 2945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type == STRING_SPLIT_SUBSTRINGS) { 2946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(key_pattern->IsString()); 2947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0); 2948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache = heap->string_split_cache(); 2949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(type == REGEXP_MULTIPLE_INDICES); 2951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(key_pattern->IsFixedArray()); 2952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache = heap->regexp_multiple_cache(); 2953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t hash = key_string->Hash(); 2956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & 2957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~(kArrayEntriesPerCacheEntry - 1)); 2958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cache->get(index + kStringOffset) == key_string && 2959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->get(index + kPatternOffset) == key_pattern) { 2960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return cache->get(index + kArrayOffset); 2961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index = 2963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); 2964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cache->get(index + kStringOffset) == key_string && 2965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->get(index + kPatternOffset) == key_pattern) { 2966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return cache->get(index + kArrayOffset); 2967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Smi::FromInt(0); 2969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpResultsCache::Enter(Isolate* isolate, Handle<String> key_string, 2973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> key_pattern, 2974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> value_array, 2975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ResultsCacheType type) { 2976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 2977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> cache; 2978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!key_string->IsInternalizedString()) return; 2979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type == STRING_SPLIT_SUBSTRINGS) { 2980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(key_pattern->IsString()); 2981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!key_pattern->IsInternalizedString()) return; 2982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache = factory->string_split_cache(); 2983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(type == REGEXP_MULTIPLE_INDICES); 2985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(key_pattern->IsFixedArray()); 2986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache = factory->regexp_multiple_cache(); 2987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t hash = key_string->Hash(); 2990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & 2991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~(kArrayEntriesPerCacheEntry - 1)); 2992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cache->get(index + kStringOffset) == Smi::FromInt(0)) { 2993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index + kStringOffset, *key_string); 2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index + kPatternOffset, *key_pattern); 2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index + kArrayOffset, *value_array); 2996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t index2 = 2998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); 2999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) { 3000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index2 + kStringOffset, *key_string); 3001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index2 + kPatternOffset, *key_pattern); 3002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index2 + kArrayOffset, *value_array); 3003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index2 + kStringOffset, Smi::FromInt(0)); 3005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index2 + kPatternOffset, Smi::FromInt(0)); 3006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index2 + kArrayOffset, Smi::FromInt(0)); 3007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index + kStringOffset, *key_string); 3008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index + kPatternOffset, *key_pattern); 3009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(index + kArrayOffset, *value_array); 3010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the array is a reasonably short list of substrings, convert it into a 3013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // list of internalized strings. 3014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) { 3015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < value_array->length(); i++) { 3016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> str(String::cast(value_array->get(i)), isolate); 3017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> internalized_str = factory->InternalizeString(str); 3018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_array->set(i, *internalized_str); 3019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert backing store to a copy-on-write array. 3022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map()); 3023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpResultsCache::Clear(FixedArray* cache) { 3027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kRegExpResultsCacheSize; i++) { 3028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache->set(i, Smi::FromInt(0)); 3029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Heap::FullSizeNumberStringCacheLength() { 3034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the size of the number string cache based on the max newspace size. 3035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The number string cache has a minimum size based on twice the initial cache 3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // size to ensure that it is bigger after being made 'full size'. 3037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int number_string_cache_size = max_semi_space_size_ / 512; 3038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_string_cache_size = Max(kInitialNumberStringCacheSize * 2, 3039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Min(0x4000, number_string_cache_size)); 3040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There is a string and a number per entry so the length is twice the number 3041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of entries. 3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return number_string_cache_size * 2; 3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::FlushNumberStringCache() { 3047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Flush the number to string cache. 3048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int len = number_string_cache()->length(); 3049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < len; i++) { 3050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_string_cache()->set_undefined(i); 3051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::FlushAllocationSitesScratchpad() { 3056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < allocation_sites_scratchpad_length_; i++) { 3057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_sites_scratchpad()->set_undefined(i); 3058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_sites_scratchpad_length_ = 0; 3060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::InitializeAllocationSitesScratchpad() { 3064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(allocation_sites_scratchpad()->length() == 3065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kAllocationSiteScratchpadSize); 3066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kAllocationSiteScratchpadSize; i++) { 3067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_sites_scratchpad()->set_undefined(i); 3068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::AddAllocationSiteToScratchpad(AllocationSite* site, 3073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScratchpadSlotMode mode) { 3074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation_sites_scratchpad_length_ < kAllocationSiteScratchpadSize) { 3075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We cannot use the normal write-barrier because slots need to be 3076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // recorded with non-incremental marking as well. We have to explicitly 3077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // record the slot to take evacuation candidates into account. 3078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_sites_scratchpad()->set(allocation_sites_scratchpad_length_, 3079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site, SKIP_WRITE_BARRIER); 3080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** slot = allocation_sites_scratchpad()->RawFieldOfElementAt( 3081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_sites_scratchpad_length_); 3082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == RECORD_SCRATCHPAD_SLOT) { 3084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We need to allow slots buffer overflow here since the evacuation 3085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // candidates are not part of the global list of old space pages and 3086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // releasing an evacuation candidate due to a slots buffer overflow 3087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // results in lost pages. 3088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->RecordSlot(slot, slot, *slot, 3089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlotsBuffer::IGNORE_OVERFLOW); 3090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_sites_scratchpad_length_++; 3092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMap* Heap::MapForExternalArrayType(ExternalArrayType array_type) { 3097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Map::cast(roots_[RootIndexForExternalArrayType(array_type)]); 3098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::RootListIndex Heap::RootIndexForExternalArrayType( 3102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type) { 3103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (array_type) { 3104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ARRAY_TYPE_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \ 3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kExternal##Type##Array: \ 3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kExternal##Type##ArrayMapRootIndex; 3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(ARRAY_TYPE_TO_ROOT_INDEX) 3109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ARRAY_TYPE_TO_ROOT_INDEX 3110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 3112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kUndefinedValueRootIndex; 3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMap* Heap::MapForFixedTypedArray(ExternalArrayType array_type) { 3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Map::cast(roots_[RootIndexForFixedTypedArray(array_type)]); 3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::RootListIndex Heap::RootIndexForFixedTypedArray( 3124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type) { 3125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (array_type) { 3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ARRAY_TYPE_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \ 3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kExternal##Type##Array: \ 3128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kFixed##Type##ArrayMapRootIndex; 3129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(ARRAY_TYPE_TO_ROOT_INDEX) 3131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ARRAY_TYPE_TO_ROOT_INDEX 3132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 3134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 3135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kUndefinedValueRootIndex; 3136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::RootListIndex Heap::RootIndexForEmptyExternalArray( 3141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elementsKind) { 3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (elementsKind) { 3143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ELEMENT_KIND_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \ 3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case EXTERNAL_##TYPE##_ELEMENTS: \ 3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kEmptyExternal##Type##ArrayRootIndex; 3146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(ELEMENT_KIND_TO_ROOT_INDEX) 3148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ELEMENT_KIND_TO_ROOT_INDEX 3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 3151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 3152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kUndefinedValueRootIndex; 3153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::RootListIndex Heap::RootIndexForEmptyFixedTypedArray( 3158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elementsKind) { 3159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (elementsKind) { 3160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ELEMENT_KIND_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \ 3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case TYPE##_ELEMENTS: \ 3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kEmptyFixed##Type##ArrayRootIndex; 3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(ELEMENT_KIND_TO_ROOT_INDEX) 3165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ELEMENT_KIND_TO_ROOT_INDEX 3166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 3167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 3168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kUndefinedValueRootIndex; 3169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochExternalArray* Heap::EmptyExternalArrayForMap(Map* map) { 3174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ExternalArray::cast( 3175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch roots_[RootIndexForEmptyExternalArray(map->elements_kind())]); 3176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFixedTypedArrayBase* Heap::EmptyFixedTypedArrayForMap(Map* map) { 3180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FixedTypedArrayBase::cast( 3181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]); 3182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateForeign(Address address, 3186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure) { 3187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Statically ensure that it is safe to allocate foreigns in paged spaces. 3188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize); 3189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; 3190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Foreign* result; 3191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = Allocate(foreign_map(), space); 3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_foreign_address(address); 3194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateByteArray(int length, PretenureFlag pretenure) { 3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length < 0 || length > ByteArray::kMaxLength) { 3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); 3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = ByteArray::SizeFor(length); 3203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); 3204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(byte_array_map()); 3211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ByteArray::cast(result)->set_length(length); 3212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateFillerObjectAt(Address addr, int size) { 3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == 0) return; 3218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* filler = HeapObject::FromAddress(addr); 3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == kPointerSize) { 3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filler->set_map_no_write_barrier(one_pointer_filler_map()); 3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (size == 2 * kPointerSize) { 3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filler->set_map_no_write_barrier(two_pointer_filler_map()); 3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filler->set_map_no_write_barrier(free_space_map()); 3225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FreeSpace::cast(filler)->set_size(size); 3226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CanMoveObjectStart(HeapObject* object) { 3231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address address = object->address(); 3232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_in_old_pointer_space = InOldPointerSpace(address); 3233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_in_old_data_space = InOldDataSpace(address); 3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (lo_space()->Contains(object)) return false; 3236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Page* page = Page::FromAddress(address); 3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We can move the object start if: 3239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (1) the object is not in old pointer or old data space, 3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (2) the page of the object was already swept, 3241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (3) the page was already concurrently swept. This case is an optimization 3242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for concurrent sweeping. The WasSwept predicate for concurrently swept 3243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pages is set after sweeping all pages. 3244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (!is_in_old_pointer_space && !is_in_old_data_space) || 3245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch page->WasSwept() || page->SweepingCompleted(); 3246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::AdjustLiveBytes(Address address, int by, InvocationMode mode) { 3250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (incremental_marking()->IsMarking() && 3251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Marking::IsBlack(Marking::MarkBitFrom(address))) { 3252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == FROM_GC) { 3253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::IncrementLiveBytesFromGC(address, by); 3254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::IncrementLiveBytesFromMutator(address, by); 3256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object, 3262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_to_trim) { 3263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize; 3264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int bytes_to_trim = elements_to_trim * element_size; 3265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map = object->map(); 3266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For now this trick is only applied to objects in new and paged space. 3268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In large object space the object's start must coincide with chunk 3269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and thus the trick is just not applicable. 3270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!lo_space()->Contains(object)); 3271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->map() != fixed_cow_array_map()); 3272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); 3274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); 3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); 3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int len = object->length(); 3278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(elements_to_trim <= len); 3279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calculate location of new array start. 3281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address new_start = object->address() + bytes_to_trim; 3282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Technically in new space this write might be omitted (except for 3284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // debug mode which iterates through the heap), but to play safer 3285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we still do it. 3286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateFillerObjectAt(object->address(), bytes_to_trim); 3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize header of the trimmed array. Since left trimming is only 3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // performed on pages which are not concurrently swept creating a filler 3290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object does not require synchronization. 3291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(CanMoveObjectStart(object)); 3292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** former_start = HeapObject::RawField(object, 0); 3293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int new_start_index = elements_to_trim * (element_size / kPointerSize); 3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch former_start[new_start_index] = map; 3295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim); 3296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase* new_object = 3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase::cast(HeapObject::FromAddress(new_start)); 3298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Maintain consistency of live bytes during incremental marking 3300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch marking()->TransferMark(object->address(), new_start); 3301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AdjustLiveBytes(new_start, -bytes_to_trim, Heap::FROM_MUTATOR); 3302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Notify the heap profiler of change in object layout. 3304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OnMoveEvent(new_object, object, new_object->Size()); 3305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_object; 3306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Force instantiation of templatized method. 3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate 3311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RightTrimFixedArray<Heap::FROM_GC>(FixedArrayBase*, int); 3312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate 3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RightTrimFixedArray<Heap::FROM_MUTATOR>(FixedArrayBase*, int); 3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<Heap::InvocationMode mode> 3317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) { 3318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize; 3319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int bytes_to_trim = elements_to_trim * element_size; 3320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For now this trick is only applied to objects in new and paged space. 3322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object->map() != fixed_cow_array_map()); 3323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int len = object->length(); 3325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(elements_to_trim < len); 3326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calculate location of new array end. 3328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address new_end = object->address() + object->Size() - bytes_to_trim; 3329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Technically in new space this write might be omitted (except for 3331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // debug mode which iterates through the heap), but to play safer 3332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we still do it. 3333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We do not create a filler for objects in large object space. 3334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(hpayer): We should shrink the large object page if the size 3335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the object changed significantly. 3336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!lo_space()->Contains(object)) { 3337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateFillerObjectAt(new_end, bytes_to_trim); 3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize header of the trimmed array. We are storing the new length 3341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // using release store after creating a filler for the left-over space to 3342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // avoid races with the sweeper thread. 3343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->synchronized_set_length(len - elements_to_trim); 3344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Maintain consistency of live bytes during incremental marking 3346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AdjustLiveBytes(object->address(), -bytes_to_trim, mode); 3347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Notify the heap profiler of change in object layout. The array may not be 3349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // moved during GC, and size has to be adjusted nevertheless. 3350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapProfiler* profiler = isolate()->heap_profiler(); 3351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (profiler->is_tracking_allocations()) { 3352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch profiler->UpdateObjectSizeEvent(object->address(), object->Size()); 3353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateExternalArray(int length, 3358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type, 3359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* external_pointer, 3360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure) { 3361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = ExternalArray::kAlignedSize; 3362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); 3363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 3366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(MapForExternalArrayType(array_type)); 3370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArray::cast(result)->set_length(length); 3371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArray::cast(result)->set_external_pointer(external_pointer); 3372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ForFixedTypedArray(ExternalArrayType array_type, int* element_size, 3376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind* element_kind) { 3377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (array_type) { 3378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 3379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kExternal##Type##Array: \ 3380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *element_size = size; \ 3381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *element_kind = TYPE##_ELEMENTS; \ 3382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 3383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(TYPED_ARRAY_CASE) 3385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef TYPED_ARRAY_CASE 3386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 3388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *element_size = 0; // Bogus 3389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *element_kind = UINT8_ELEMENTS; // Bogus 3390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 3391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFixedTypedArray(int length, 3396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type, 3397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure) { 3398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int element_size; 3399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind; 3400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ForFixedTypedArray(array_type, &element_size, &elements_kind); 3401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = OBJECT_POINTER_ALIGN(length * element_size + 3402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedTypedArrayBase::kDataOffset); 3403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_HOST_ARCH_64_BIT 3404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (array_type == kExternalFloat64Array) { 3405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size += kPointerSize; 3406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); 3409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object; 3411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 3412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&object)) return allocation; 3413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (array_type == kExternalFloat64Array) { 3415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object = EnsureDoubleAligned(this, object, size); 3416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->set_map(MapForFixedTypedArray(array_type)); 3419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object); 3420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->set_length(length); 3421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memset(elements->DataPtr(), 0, elements->DataSize()); 3422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return elements; 3423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateCode(int object_size, bool immovable) { 3427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment)); 3428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 3429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRaw(object_size, CODE_SPACE, CODE_SPACE); 3430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (immovable) { 3435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address address = result->address(); 3436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code objects which should stay at a fixed address are allocated either 3437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in the first page of code space (objects on the first page of each space 3438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // are never moved) or in large object space. 3439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!code_space_->FirstPage()->Contains(address) && 3440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::FromAddress(address)->owner()->identity() != LO_SPACE) { 3441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Discard the first code allocation, which was on a page where it could 3442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be moved. 3443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateFillerObjectAt(result->address(), object_size); 3444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE); 3445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OnAllocationEvent(result, object_size); 3447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(code_map()); 3451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* code = Code::cast(result); 3452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(isolate_->code_range() == NULL || !isolate_->code_range()->valid() || 3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->code_range()->contains(code->address())); 3454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->set_gc_metadata(Smi::FromInt(0)); 3455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->set_ic_age(global_ic_age_); 3456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return code; 3457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyCode(Code* code) { 3461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation; 3462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* new_constant_pool; 3463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_enable_ool_constant_pool && 3464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->constant_pool() != empty_constant_pool_array()) { 3465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the constant pool, since edits to the copied code may modify 3466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the constant pool. 3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = CopyConstantPoolArray(code->constant_pool()); 3468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&new_constant_pool)) return allocation; 3469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_constant_pool = empty_constant_pool_array(); 3471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate an object the same size as the code object. 3475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int obj_size = code->Size(); 3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE); 3477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy code object. 3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address old_addr = code->address(); 3481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address new_addr = result->address(); 3482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CopyBlock(new_addr, old_addr, obj_size); 3483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* new_code = Code::cast(result); 3484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update the constant pool. 3486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_code->set_constant_pool(new_constant_pool); 3487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Relocate the copy. 3489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(isolate_->code_range() == NULL || !isolate_->code_range()->valid() || 3490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->code_range()->contains(code->address())); 3491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_code->Relocate(new_addr - old_addr); 3492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_code; 3493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyCode(Code* code, Vector<byte> reloc_info) { 3497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate ByteArray and ConstantPoolArray before the Code object, so that we 3498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // do not risk leaving uninitialized Code object (and breaking the heap). 3499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ByteArray* reloc_info_array; 3500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateByteArray(reloc_info.length(), TENURED); 3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&reloc_info_array)) return allocation; 3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* new_constant_pool; 3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_enable_ool_constant_pool && 3507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->constant_pool() != empty_constant_pool_array()) { 3508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the constant pool, since edits to the copied code may modify 3509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the constant pool. 3510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = CopyConstantPoolArray(code->constant_pool()); 3511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&new_constant_pool)) return allocation; 3512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_constant_pool = empty_constant_pool_array(); 3514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); 3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int new_obj_size = Code::SizeFor(new_body_size); 3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address old_addr = code->address(); 3521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t relocation_offset = 3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<size_t>(code->instruction_end() - old_addr); 3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 3527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE); 3528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy code object. 3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address new_addr = result->address(); 3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy header and instructions. 3534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CopyBytes(new_addr, old_addr, relocation_offset); 3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* new_code = Code::cast(result); 3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_code->set_relocation_info(reloc_info_array); 3538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update constant pool. 3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_code->set_constant_pool(new_constant_pool); 3541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy patched rinfo. 3543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CopyBytes(new_code->relocation_start(), reloc_info.start(), 3544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<size_t>(reloc_info.length())); 3545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Relocate the copy. 3547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(isolate_->code_range() == NULL || !isolate_->code_range()->valid() || 3548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->code_range()->contains(code->address())); 3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_code->Relocate(new_addr - old_addr); 3550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 3552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_heap) code->ObjectVerify(); 3553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_code; 3555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::InitializeAllocationMemento(AllocationMemento* memento, 3559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite* allocation_site) { 3560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memento->set_map_no_write_barrier(allocation_memento_map()); 3561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(allocation_site->map() == allocation_site_map()); 3562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER); 3563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring) { 3564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site->IncrementMementoCreateCount(); 3565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::Allocate(Map* map, AllocationSpace space, 3570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite* allocation_site) { 3571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(gc_state_ == NOT_IN_GC); 3572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(map->instance_type() != MAP_TYPE); 3573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If allocation failures are disallowed, we may allocate in a different 3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // space when new space is full and the object is not a large object. 3575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace retry_space = 3576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); 3577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = map->instance_size(); 3578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation_site != NULL) { 3579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size += AllocationMemento::kSize; 3580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, retry_space); 3583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No need for write barrier since object is white and map is in old space. 3585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(map); 3586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation_site != NULL) { 3587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( 3588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Address>(result) + map->instance_size()); 3589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeAllocationMemento(alloc_memento, allocation_site); 3590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::InitializeJSObjectFromMap(JSObject* obj, FixedArray* properties, 3596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map) { 3597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->set_properties(properties); 3598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->initialize_elements(); 3599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(1240798): Initialize the object's body using valid initial values 3600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // according to the object's initial map. For example, if the map's 3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instance type is JS_ARRAY_TYPE, the length field should be initialized 3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to a number (e.g. Smi::FromInt(0)) and the elements initialized to a 3603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // fixed array (e.g. Heap::empty_fixed_array()). Currently, the object 3604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // verification code has to cope with (temporarily) invalid objects. See 3605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for example, JSArray::JSArrayVerify). 3606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* filler; 3607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We cannot always fill with one_pointer_filler_map because objects 3608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // created from API functions expect their internal fields to be initialized 3609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with undefined_value. 3610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pre-allocated fields need to be initialized with undefined_value as well 3611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // so that object accesses before the constructor completes (e.g. in the 3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // debugger) will not cause a crash. 3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map->constructor()->IsJSFunction() && 3614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction::cast(map->constructor()) 3615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->IsInobjectSlackTrackingInProgress()) { 3616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We might want to shrink the object later. 3617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(obj->GetInternalFieldCount() == 0); 3618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filler = Heap::one_pointer_filler_map(); 3619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filler = Heap::undefined_value(); 3621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->InitializeBody(map, Heap::undefined_value(), filler); 3623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateJSObjectFromMap( 3627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map, PretenureFlag pretenure, bool allocate_properties, 3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite* allocation_site) { 3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSFunctions should be allocated using AllocateFunction to be 3630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // properly initialized. 3631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(map->instance_type() != JS_FUNCTION_TYPE); 3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Both types of global objects should be allocated using 3634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // AllocateGlobalObject to be properly initialized. 3635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); 3636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); 3637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the backing storage for the properties. 3639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* properties; 3640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocate_properties) { 3641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int prop_size = map->InitialPropertiesLength(); 3642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(prop_size >= 0); 3643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateFixedArray(prop_size, pretenure); 3645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&properties)) return allocation; 3646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch properties = empty_fixed_array(); 3649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the JSObject. 3652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = map->instance_size(); 3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure); 3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject* js_obj; 3655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = Allocate(map, space, allocation_site); 3656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&js_obj)) return allocation; 3657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the JSObject. 3659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeJSObjectFromMap(js_obj, properties, map); 3660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(js_obj->HasFastElements() || js_obj->HasExternalArrayElements() || 3661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch js_obj->HasFixedTypedArrayElements()); 3662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return js_obj; 3663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateJSObject(JSFunction* constructor, 3667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure, 3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite* allocation_site) { 3669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(constructor->has_initial_map()); 3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the object based on the constructors initial map. 3672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateJSObjectFromMap( 3673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor->initial_map(), pretenure, true, allocation_site); 3674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure result is NOT a global object if valid. 3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj; 3677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!allocation.To(&obj) || !obj->IsGlobalObject()); 3678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return allocation; 3680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) { 3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Never used to copy functions. If functions need to be copied we 3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // have to be careful to clear the literals array. 3686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(!source->IsJSFunction()); 3687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make the clone. 3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map = source->map(); 3690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int object_size = map->instance_size(); 3691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* clone; 3692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type())); 3694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER; 3696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we're forced to always allocate, we use the general allocation 3698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // functions which may leave us with an object in old space. 3699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (always_allocate()) { 3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE); 3703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&clone)) return allocation; 3704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address clone_address = clone->address(); 3706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CopyBlock(clone_address, source->address(), object_size); 3707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update write barrier for all fields that lie beyond the header. 3708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrites(clone_address, JSObject::kHeaderSize, 3709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (object_size - JSObject::kHeaderSize) / kPointerSize); 3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch wb_mode = SKIP_WRITE_BARRIER; 3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int adjusted_object_size = 3715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site != NULL ? object_size + AllocationMemento::kSize : object_size; 3716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 3717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRaw(adjusted_object_size, NEW_SPACE, NEW_SPACE); 3718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&clone)) return allocation; 3719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(InNewSpace(clone)); 3721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since we know the clone is allocated in new space, we can copy 3722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the contents without worrying about updating the write barrier. 3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CopyBlock(clone->address(), source->address(), object_size); 3724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (site != NULL) { 3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( 3727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Address>(clone) + object_size); 3728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeAllocationMemento(alloc_memento, site); 3729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(JSObject::cast(clone)->GetElementsKind() == 3733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch source->GetElementsKind()); 3734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase* elements = FixedArrayBase::cast(source->elements()); 3735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* properties = FixedArray::cast(source->properties()); 3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update elements if necessary. 3737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements->length() > 0) { 3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase* elem; 3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation; 3741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements->map() == fixed_cow_array_map()) { 3742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = FixedArray::cast(elements); 3743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->HasFastDoubleElements()) { 3744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = CopyFixedDoubleArray(FixedDoubleArray::cast(elements)); 3745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation = CopyFixedArray(FixedArray::cast(elements)); 3747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&elem)) return allocation; 3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::cast(clone)->set_elements(elem, wb_mode); 3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update properties if necessary. 3753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (properties->length() > 0) { 3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* prop; 3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = CopyFixedArray(properties); 3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&prop)) return allocation; 3758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::cast(clone)->set_properties(prop, wb_mode); 3760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the new clone. 3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return clone; 3763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteOneByteData(Vector<const char> vector, uint8_t* chars, 3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int len) { 3768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only works for one byte strings. 3769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(vector.length() == len); 3770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemCopy(chars, vector.start(), len); 3771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteTwoByteData(Vector<const char> vector, uint16_t* chars, 3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int len) { 3775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const uint8_t* stream = reinterpret_cast<const uint8_t*>(vector.start()); 3776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned stream_length = vector.length(); 3777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (stream_length != 0) { 3778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned consumed = 0; 3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t c = unibrow::Utf8::ValueOf(stream, stream_length, &consumed); 3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(c != unibrow::Utf8::kBadChar); 3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(consumed <= stream_length); 3782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stream_length -= consumed; 3783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stream += consumed; 3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { 3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch len -= 2; 3786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (len < 0) break; 3787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *chars++ = unibrow::Utf16::LeadSurrogate(c); 3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *chars++ = unibrow::Utf16::TrailSurrogate(c); 3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch len -= 1; 3791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (len < 0) break; 3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *chars++ = c; 3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(stream_length == 0); 3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(len == 0); 3797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteOneByteData(String* s, uint8_t* chars, int len) { 3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(s->length() == len); 3802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::WriteToFlat(s, chars, 0, len); 3803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteTwoByteData(String* s, uint16_t* chars, int len) { 3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(s->length() == len); 3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::WriteToFlat(s, chars, 0, len); 3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <bool is_one_byte, typename T> 3813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateInternalizedStringImpl(T t, int chars, 3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t hash_field) { 3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(chars >= 0); 3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute map and object size. 3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size; 3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map; 3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(0, chars); 3821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(String::kMaxLength, chars); 3822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_one_byte) { 3823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map = one_byte_internalized_string_map(); 3824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size = SeqOneByteString::SizeFor(chars); 3825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map = internalized_string_map(); 3827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size = SeqTwoByteString::SizeFor(chars); 3828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED); 3830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate string. 3832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 3835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(map); 3839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set length and hash fields of the allocated string. 3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String* answer = String::cast(result); 3841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch answer->set_length(chars); 3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch answer->set_hash_field(hash_field); 3843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(size, answer->Size()); 3845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_one_byte) { 3847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars); 3848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars); 3850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return answer; 3852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Need explicit instantiations. 3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate AllocationResult Heap::AllocateInternalizedStringImpl<true>(String*, 3857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int, 3858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t); 3859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate AllocationResult Heap::AllocateInternalizedStringImpl<false>(String*, 3860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int, 3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t); 3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate AllocationResult Heap::AllocateInternalizedStringImpl<false>( 3863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const char>, int, uint32_t); 3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawOneByteString(int length, 3867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure) { 3868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(0, length); 3869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(String::kMaxLength, length); 3870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = SeqOneByteString::SizeFor(length); 3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(size <= SeqOneByteString::kMaxSize); 3872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); 3873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 3877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Partially initialize the object. 3881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(one_byte_string_map()); 3882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::cast(result)->set_length(length); 3883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::cast(result)->set_hash_field(String::kEmptyHashField); 3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(size, HeapObject::cast(result)->Size()); 3885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawTwoByteString(int length, 3891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure) { 3892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(0, length); 3893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(String::kMaxLength, length); 3894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = SeqTwoByteString::SizeFor(length); 3895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(size <= SeqTwoByteString::kMaxSize); 3896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); 3897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 3901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Partially initialize the object. 3905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(string_map()); 3906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::cast(result)->set_length(length); 3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::cast(result)->set_hash_field(String::kEmptyHashField); 3908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(size, HeapObject::cast(result)->Size()); 3909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateEmptyFixedArray() { 3914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = FixedArray::SizeFor(0); 3915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 3916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 3918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); 3919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 3920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the object. 3922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(fixed_array_map()); 3923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray::cast(result)->set_length(0); 3924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateEmptyExternalArray( 3929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type) { 3930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AllocateExternalArray(0, array_type, NULL, TENURED); 3931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyAndTenureFixedCOWArray(FixedArray* src) { 3935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!InNewSpace(src)) { 3936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return src; 3937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int len = src->length(); 3940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj; 3941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRawFixedArray(len, TENURED); 3943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return allocation; 3944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->set_map_no_write_barrier(fixed_array_map()); 3946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* result = FixedArray::cast(obj); 3947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_length(len); 3948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the content 3950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 3951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 3952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); 3953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(mvstanton): The map is set twice because of protection against calling 3955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // set() on a COW FixedArray. Issue v8:3221 created to track this, and 3956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we might then be able to remove this whole method. 3957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject::cast(obj)->set_map_no_write_barrier(fixed_cow_array_map()); 3958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateEmptyFixedTypedArray( 3963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type) { 3964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AllocateFixedTypedArray(0, array_type, TENURED); 3965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) { 3969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int len = src->length(); 3970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj; 3971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED); 3973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return allocation; 3974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (InNewSpace(obj)) { 3976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->set_map_no_write_barrier(map); 3977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CopyBlock(obj->address() + kPointerSize, src->address() + kPointerSize, 3978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray::SizeFor(len) - kPointerSize); 3979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return obj; 3980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->set_map_no_write_barrier(map); 3982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* result = FixedArray::cast(obj); 3983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_length(len); 3984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the content 3986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 3987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 3988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); 3989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src, 3994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map) { 3995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int len = src->length(); 3996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj; 3997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRawFixedDoubleArray(len, NOT_TENURED); 3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return allocation; 4000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->set_map_no_write_barrier(map); 4002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CopyBlock(obj->address() + FixedDoubleArray::kLengthOffset, 4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch src->address() + FixedDoubleArray::kLengthOffset, 4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset); 4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return obj; 4006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src, 4010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map) { 4011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj; 4012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src->is_extended_layout()) { 4013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantPoolArray::NumberOfEntries small(src, 4014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantPoolArray::SMALL_SECTION); 4015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantPoolArray::NumberOfEntries extended( 4016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch src, ConstantPoolArray::EXTENDED_SECTION); 4017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 4018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateExtendedConstantPoolArray(small, extended); 4019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return allocation; 4020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantPoolArray::NumberOfEntries small(src, 4022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantPoolArray::SMALL_SECTION); 4023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateConstantPoolArray(small); 4024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return allocation; 4025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->set_map_no_write_barrier(map); 4027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CopyBlock(obj->address() + ConstantPoolArray::kFirstEntryOffset, 4028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch src->address() + ConstantPoolArray::kFirstEntryOffset, 4029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch src->size() - ConstantPoolArray::kFirstEntryOffset); 4030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return obj; 4031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawFixedArray(int length, 4035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure) { 4036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length < 0 || length > FixedArray::kMaxLength) { 4037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); 4038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = FixedArray::SizeFor(length); 4040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure); 4041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AllocateRaw(size, space, OLD_POINTER_SPACE); 4043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFixedArrayWithFiller(int length, 4047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure, 4048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* filler) { 4049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length >= 0); 4050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(empty_fixed_array()->IsFixedArray()); 4051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length == 0) return empty_fixed_array(); 4052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!InNewSpace(filler)); 4054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 4055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRawFixedArray(length, pretenure); 4057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 4058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(fixed_array_map()); 4061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* array = FixedArray::cast(result); 4062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array->set_length(length); 4063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemsetPointer(array->data_start(), filler, length); 4064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array; 4065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) { 4069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AllocateFixedArrayWithFiller(length, pretenure, undefined_value()); 4070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateUninitializedFixedArray(int length) { 4074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length == 0) return empty_fixed_array(); 4075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj; 4077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRawFixedArray(length, NOT_TENURED); 4079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&obj)) return allocation; 4080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->set_map_no_write_barrier(fixed_array_map()); 4083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray::cast(obj)->set_length(length); 4084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return obj; 4085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateUninitializedFixedDoubleArray( 4089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length, PretenureFlag pretenure) { 4090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length == 0) return empty_fixed_array(); 4091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* elements; 4093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRawFixedDoubleArray(length, pretenure); 4094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&elements)) return allocation; 4095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->set_map_no_write_barrier(fixed_double_array_map()); 4097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::cast(elements)->set_length(length); 4098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return elements; 4099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawFixedDoubleArray(int length, 4103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure) { 4104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length < 0 || length > FixedDoubleArray::kMaxLength) { 4105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); 4106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = FixedDoubleArray::SizeFor(length); 4108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_HOST_ARCH_64_BIT 4109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size += kPointerSize; 4110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 4111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); 4112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object; 4114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 4116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&object)) return allocation; 4117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return EnsureDoubleAligned(this, object, size); 4120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateConstantPoolArray( 4124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ConstantPoolArray::NumberOfEntries& small) { 4125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(small.are_in_range(0, ConstantPoolArray::kMaxSmallEntriesPerType)); 4126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = ConstantPoolArray::SizeFor(small); 4127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_HOST_ARCH_64_BIT 4128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size += kPointerSize; 4129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 4130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED); 4131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object; 4133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_POINTER_SPACE); 4135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&object)) return allocation; 4136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object = EnsureDoubleAligned(this, object, size); 4138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->set_map_no_write_barrier(constant_pool_array_map()); 4139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object); 4141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool->Init(small); 4142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool->ClearPtrEntries(isolate()); 4143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant_pool; 4144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateExtendedConstantPoolArray( 4148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ConstantPoolArray::NumberOfEntries& small, 4149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ConstantPoolArray::NumberOfEntries& extended) { 4150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(small.are_in_range(0, ConstantPoolArray::kMaxSmallEntriesPerType)); 4151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(extended.are_in_range(0, kMaxInt)); 4152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = ConstantPoolArray::SizeForExtended(small, extended); 4153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_HOST_ARCH_64_BIT 4154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size += kPointerSize; 4155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 4156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED); 4157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object; 4159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = AllocateRaw(size, space, OLD_POINTER_SPACE); 4161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&object)) return allocation; 4162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object = EnsureDoubleAligned(this, object, size); 4164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->set_map_no_write_barrier(constant_pool_array_map()); 4165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object); 4167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool->InitExtended(small, extended); 4168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_pool->ClearPtrEntries(isolate()); 4169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant_pool; 4170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateEmptyConstantPoolArray() { 4174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantPoolArray::NumberOfEntries small(0, 0, 0, 0); 4175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = ConstantPoolArray::SizeFor(small); 4176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 4177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 4179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); 4180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 4181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(constant_pool_array_map()); 4183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantPoolArray::cast(result)->Init(small); 4184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 4185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateSymbol() { 4189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Statically ensure that it is safe to allocate symbols in paged spaces. 4190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(Symbol::kSize <= Page::kMaxRegularHeapObjectSize); 4191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* result; 4193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = 4194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRaw(Symbol::kSize, OLD_POINTER_SPACE, OLD_POINTER_SPACE); 4195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 4196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_map_no_write_barrier(symbol_map()); 4198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate a random hash value. 4200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int hash; 4201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int attempts = 0; 4202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { 4203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = isolate()->random_number_generator()->NextInt() & Name::kHashBitMask; 4204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch attempts++; 4205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (hash == 0 && attempts < 30); 4206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (hash == 0) hash = 1; // never return 0 4207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Symbol::cast(result) 4209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->set_hash_field(Name::kIsNotArrayIndexMask | (hash << Name::kHashShift)); 4210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Symbol::cast(result)->set_name(undefined_value()); 4211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Symbol::cast(result)->set_flags(Smi::FromInt(0)); 4212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!Symbol::cast(result)->is_private()); 4214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 4215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateStruct(InstanceType type) { 4219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map; 4220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (type) { 4221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define MAKE_CASE(NAME, Name, name) \ 4222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NAME##_TYPE: \ 4223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map = name##_map(); \ 4224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STRUCT_LIST(MAKE_CASE) 4226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef MAKE_CASE 4227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 4228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 4229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return exception(); 4230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = map->instance_size(); 4232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED); 4233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Struct* result; 4234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationResult allocation = Allocate(map, space); 4236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation.To(&result)) return allocation; 4237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->InitializeBody(size); 4239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 4240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::IsHeapIterable() { 4244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(hpayer): This function is not correct. Allocation folding in old 4245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // space breaks the iterability. 4246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_space_top_after_last_gc_ == new_space()->top(); 4247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MakeHeapIterable() { 4251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AllowHeapAllocation::IsAllowed()); 4252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsHeapIterable()) { 4253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); 4254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mark_compact_collector()->sweeping_in_progress()) { 4256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->EnsureSweepingCompleted(); 4257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsHeapIterable()); 4259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IdleMarkCompact(const char* message) { 4263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool uncommit = false; 4264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (gc_count_at_last_idle_gc_ == gc_count_) { 4265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No GC since the last full GC, the mutator is probably not active. 4266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->compilation_cache()->Clear(); 4267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uncommit = true; 4268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CollectAllGarbage(kReduceMemoryFootprintMask, message); 4270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_idle_time_handler_.NotifyIdleMarkCompact(); 4271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_count_at_last_idle_gc_ = gc_count_; 4272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (uncommit) { 4273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.Shrink(); 4274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UncommitFromSpace(); 4275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) { 4280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->Step(step_size, 4281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementalMarking::NO_GC_VIA_STACK_GUARD, true); 4282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (incremental_marking()->IsComplete()) { 4284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IdleMarkCompact("idle notification: finalize incremental"); 4285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::WorthActivatingIncrementalMarking() { 4290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return incremental_marking()->IsStopped() && 4291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull(); 4292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::IdleNotification(int idle_time_in_ms) { 4296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If incremental marking is off, we do not perform idle notification. 4297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_incremental_marking) return true; 4298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::ElapsedTimer timer; 4299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch timer.Start(); 4300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( 4301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch idle_time_in_ms); 4302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HistogramTimerScope idle_notification_scope( 4303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->counters()->gc_idle_notification()); 4304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCIdleTimeHandler::HeapState heap_state; 4306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.contexts_disposed = contexts_disposed_; 4307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects()); 4308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); 4309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(ulan): Start incremental marking only for large heaps. 4310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.can_start_incremental_marking = 4311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->ShouldActivate(); 4312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.sweeping_in_progress = 4313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->sweeping_in_progress(); 4314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.mark_compact_speed_in_bytes_per_ms = 4315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); 4316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>( 4317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); 4318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.scavenge_speed_in_bytes_per_ms = 4319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); 4320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.available_new_space_memory = new_space_.Available(); 4321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.new_space_capacity = new_space_.Capacity(); 4322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_state.new_space_allocation_throughput_in_bytes_per_ms = 4323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<size_t>( 4324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond()); 4325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCIdleTimeAction action = 4327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); 4328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool result = false; 4330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (action.type) { 4331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DONE: 4332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = true; 4333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DO_INCREMENTAL_MARKING: 4335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (incremental_marking()->IsStopped()) { 4336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->Start(); 4337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AdvanceIdleIncrementalMarking(action.parameter); 4339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DO_FULL_GC: { 4341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HistogramTimerScope scope(isolate_->counters()->gc_context()); 4342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (contexts_disposed_) { 4343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CollectAllGarbage(kReduceMemoryFootprintMask, 4344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "idle notification: contexts disposed"); 4345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_idle_time_handler_.NotifyIdleMarkCompact(); 4346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_count_at_last_idle_gc_ = gc_count_; 4347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IdleMarkCompact("idle notification: finalize idle round"); 4349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DO_SCAVENGE: 4353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CollectGarbage(NEW_SPACE, "idle notification: scavenge"); 4354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DO_FINALIZE_SWEEPING: 4356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->EnsureSweepingCompleted(); 4357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DO_NOTHING: 4359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int actual_time_ms = static_cast<int>(timer.Elapsed().InMilliseconds()); 4363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (actual_time_ms <= idle_time_in_ms) { 4364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->gc_idle_time_limit_undershot()->AddSample( 4365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch idle_time_in_ms - actual_time_ms); 4366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->gc_idle_time_limit_overshot()->AddSample( 4368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch actual_time_ms - idle_time_in_ms); 4369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_idle_notification) { 4372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Idle notification: requested idle time %d ms, actual time %d ms [", 4373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch idle_time_in_ms, actual_time_ms); 4374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch action.Print(); 4375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("]\n"); 4376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch contexts_disposed_ = 0; 4379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 4380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 4384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::Print() { 4386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!HasBeenSetUp()) return; 4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->PrintStack(stdout); 4388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllSpaces spaces(this); 4389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { 4390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space->Print(); 4391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportCodeStatistics(const char* title) { 4396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(">>>>>> Code Stats (%s) >>>>>>\n", title); 4397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PagedSpace::ResetCodeStatistics(isolate()); 4398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We do not look for code in new space, map space, or old space. If code 4399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // somehow ends up in those spaces, we would miss it here. 4400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_->CollectCodeStatistics(); 4401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_->CollectCodeStatistics(); 4402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PagedSpace::ReportCodeStatistics(isolate()); 4403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This function expects that NewSpace's allocated objects histogram is 4407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// populated (via a call to CollectStatistics or else as a side effect of a 4408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// just-completed scavenge collection). 4409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportHeapStatistics(const char* title) { 4410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(title); 4411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(">>>>>> =============== %s (%d) =============== >>>>>>\n", title, 4412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_count_); 4413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("old_generation_allocation_limit_ %" V8_PTR_PREFIX "d\n", 4414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_generation_allocation_limit_); 4415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 4417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles(isolate_)); 4418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->global_handles()->PrintStats(); 4419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 4420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Heap statistics : "); 4422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->memory_allocator()->ReportStatistics(); 4423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("To space : "); 4424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.ReportStatistics(); 4425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Old pointer space : "); 4426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->ReportStatistics(); 4427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Old data space : "); 4428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->ReportStatistics(); 4429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Code space : "); 4430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_->ReportStatistics(); 4431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Map space : "); 4432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->ReportStatistics(); 4433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Cell space : "); 4434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_->ReportStatistics(); 4435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("PropertyCell space : "); 4436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->ReportStatistics(); 4437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Large object space : "); 4438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_->ReportStatistics(); 4439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(">>>>>> ========================================= >>>>>>\n"); 4440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // DEBUG 4443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::Contains(HeapObject* value) { return Contains(value->address()); } 4445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::Contains(Address addr) { 4448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(addr)) return false; 4449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return HasBeenSetUp() && 4450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (new_space_.ToSpaceContains(addr) || 4451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->Contains(addr) || 4452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->Contains(addr) || code_space_->Contains(addr) || 4453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->Contains(addr) || cell_space_->Contains(addr) || 4454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->Contains(addr) || 4455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_->SlowContains(addr)); 4456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::InSpace(HeapObject* value, AllocationSpace space) { 4460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return InSpace(value->address(), space); 4461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::InSpace(Address addr, AllocationSpace space) { 4465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(addr)) return false; 4466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!HasBeenSetUp()) return false; 4467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (space) { 4469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NEW_SPACE: 4470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_space_.ToSpaceContains(addr); 4471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_POINTER_SPACE: 4472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return old_pointer_space_->Contains(addr); 4473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_DATA_SPACE: 4474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return old_data_space_->Contains(addr); 4475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CODE_SPACE: 4476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return code_space_->Contains(addr); 4477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case MAP_SPACE: 4478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return map_space_->Contains(addr); 4479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CELL_SPACE: 4480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return cell_space_->Contains(addr); 4481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case PROPERTY_CELL_SPACE: 4482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return property_cell_space_->Contains(addr); 4483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LO_SPACE: 4484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return lo_space_->SlowContains(addr); 4485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case INVALID_SPACE: 4486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 4489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 4490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 4494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::Verify() { 4495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(HasBeenSetUp()); 4496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate()); 4497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer()->Verify(); 4499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mark_compact_collector()->sweeping_in_progress()) { 4501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to wait here for the sweeper threads to have an iterable heap. 4502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->EnsureSweepingCompleted(); 4503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VerifyPointersVisitor visitor; 4506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterateRoots(&visitor, VISIT_ONLY_STRONG); 4507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VerifySmisVisitor smis_visitor; 4509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterateSmiRoots(&smis_visitor); 4510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.Verify(); 4512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->Verify(&visitor); 4514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->Verify(&visitor); 4515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VerifyPointersVisitor no_dirty_regions_visitor; 4517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->Verify(&no_dirty_regions_visitor); 4518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_->Verify(&no_dirty_regions_visitor); 4519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_->Verify(&no_dirty_regions_visitor); 4520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->Verify(&no_dirty_regions_visitor); 4521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_->Verify(); 4523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 4525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ZapFromSpace() { 4528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NewSpacePageIterator it(new_space_.FromSpaceStart(), 4529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.FromSpaceEnd()); 4530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (it.has_next()) { 4531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NewSpacePage* page = it.next(); 4532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Address cursor = page->area_start(), limit = page->area_end(); 4533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cursor < limit; cursor += kPointerSize) { 4534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Memory::Address_at(cursor) = kFromSpaceZapValue; 4535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateAndMarkPointersToFromSpace(Address start, Address end, 4541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectSlotCallback callback) { 4542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address slot_address = start; 4543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We are not collecting slots on new space objects during mutation 4545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // thus we have to scan for pointers to evacuation candidates when we 4546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // promote objects. But we should not record any slots in non-black 4547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // objects. Grey object's slots would be rescanned. 4548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // White object might not survive until the end of collection 4549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it would be a violation of the invariant to record it's slots. 4550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool record_slots = false; 4551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (incremental_marking()->IsCompacting()) { 4552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit mark_bit = Marking::MarkBitFrom(HeapObject::FromAddress(start)); 4553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch record_slots = Marking::IsBlack(mark_bit); 4554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (slot_address < end) { 4557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** slot = reinterpret_cast<Object**>(slot_address); 4558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* object = *slot; 4559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the store buffer becomes overfull we mark pages as being exempt from 4560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the store buffer. These pages are scanned to find pointers that point 4561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the new space. In that case we may hit newly promoted objects and 4562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // fix the pointers before the promotion queue gets to them. Thus the 'if'. 4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsHeapObject()) { 4564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Heap::InFromSpace(object)) { 4565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch callback(reinterpret_cast<HeapObject**>(slot), 4566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject::cast(object)); 4567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* new_object = *slot; 4568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (InNewSpace(new_object)) { 4569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(Heap::InToSpace(new_object)); 4570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(new_object->IsHeapObject()); 4571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_.EnterDirectlyIntoStoreBuffer( 4572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Address>(slot)); 4573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOW_DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_object)); 4575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (record_slots && 4576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkCompactCollector::IsOnEvacuationCandidate(object)) { 4577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->RecordSlot(slot, slot, object); 4578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch slot_address += kPointerSize; 4581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 4586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef bool (*CheckStoreBufferFilter)(Object** addr); 4587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool IsAMapPointerAddress(Object** addr) { 4590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uintptr_t a = reinterpret_cast<uintptr_t>(addr); 4591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int mod = a % Map::kSize; 4592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return mod >= Map::kPointerFieldsBeginOffset && 4593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mod < Map::kPointerFieldsEndOffset; 4594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool EverythingsAPointer(Object** addr) { return true; } 4598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CheckStoreBuffer(Heap* heap, Object** current, Object** limit, 4601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object**** store_buffer_position, 4602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** store_buffer_top, 4603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckStoreBufferFilter filter, 4604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address special_garbage_start, 4605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address special_garbage_end) { 4606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* free_space_map = heap->free_space_map(); 4607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (; current < limit; current++) { 4608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* o = *current; 4609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address current_address = reinterpret_cast<Address>(current); 4610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Skip free space. 4611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (o == free_space_map) { 4612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address current_address = reinterpret_cast<Address>(current); 4613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FreeSpace* free_space = 4614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FreeSpace::cast(HeapObject::FromAddress(current_address)); 4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int skip = free_space->Size(); 4616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_address + skip <= reinterpret_cast<Address>(limit)); 4617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(skip > 0); 4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_address += skip - kPointerSize; 4619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = reinterpret_cast<Object**>(current_address); 4620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 4621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Skip the current linear allocation space between top and limit which is 4623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // unmarked with the free space map, but can contain junk. 4624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_address == special_garbage_start && 4625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch special_garbage_end != special_garbage_start) { 4626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_address = special_garbage_end - kPointerSize; 4627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = reinterpret_cast<Object**>(current_address); 4628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 4629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!(*filter)(current)) continue; 4631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_address < special_garbage_start || 4632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_address >= special_garbage_end); 4633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(reinterpret_cast<uintptr_t>(o) != kFreeListZapValue); 4634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to check that the pointer does not point into new space 4635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // without trying to cast it to a heap object since the hash field of 4636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a string can contain values like 1 and 3 which are tagged null 4637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pointers. 4638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!heap->InNewSpace(o)) continue; 4639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (**store_buffer_position < current && 4640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *store_buffer_position < store_buffer_top) { 4641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (*store_buffer_position)++; 4642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (**store_buffer_position != current || 4644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *store_buffer_position == store_buffer_top) { 4645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** obj_start = current; 4646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!(*obj_start)->IsMap()) obj_start--; 4647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 4648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check that the store buffer contains all intergenerational pointers by 4654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// scanning a page and ensuring that all pointers to young space are in the 4655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// store buffer. 4656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::OldPointerSpaceCheckStoreBuffer() { 4657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OldSpace* space = old_pointer_space(); 4658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PageIterator pages(space); 4659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer()->SortUniq(); 4661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (pages.has_next()) { 4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Page* page = pages.next(); 4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** current = reinterpret_cast<Object**>(page->area_start()); 4665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address end = page->area_end(); 4667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** store_buffer_position = store_buffer()->Start(); 4669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** store_buffer_top = store_buffer()->Top(); 4670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** limit = reinterpret_cast<Object**>(end); 4672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckStoreBuffer(this, current, limit, &store_buffer_position, 4673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_top, &EverythingsAPointer, space->top(), 4674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space->limit()); 4675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MapSpaceCheckStoreBuffer() { 4680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapSpace* space = map_space(); 4681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PageIterator pages(space); 4682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer()->SortUniq(); 4684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (pages.has_next()) { 4686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Page* page = pages.next(); 4687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** current = reinterpret_cast<Object**>(page->area_start()); 4688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address end = page->area_end(); 4690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** store_buffer_position = store_buffer()->Start(); 4692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** store_buffer_top = store_buffer()->Top(); 4693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** limit = reinterpret_cast<Object**>(end); 4695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckStoreBuffer(this, current, limit, &store_buffer_position, 4696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_top, &IsAMapPointerAddress, space->top(), 4697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space->limit()); 4698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::LargeObjectSpaceCheckStoreBuffer() { 4703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LargeObjectIterator it(lo_space()); 4704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { 4705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We only have code, sequential strings, or fixed arrays in large 4706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object space, and only fixed arrays can possibly contain pointers to 4707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the young generation. 4708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsFixedArray()) { 4709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** store_buffer_position = store_buffer()->Start(); 4710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object*** store_buffer_top = store_buffer()->Top(); 4711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** current = reinterpret_cast<Object**>(object->address()); 4712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** limit = 4713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Object**>(object->address() + object->Size()); 4714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckStoreBuffer(this, current, limit, &store_buffer_position, 4715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer_top, &EverythingsAPointer, NULL, NULL); 4716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 4720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { 4723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterateStrongRoots(v, mode); 4724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterateWeakRoots(v, mode); 4725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { 4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->VisitPointer(reinterpret_cast<Object**>(&roots_[kStringTableRootIndex])); 4730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kStringTable); 4731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode != VISIT_ALL_IN_SCAVENGE && mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { 4732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Scavenge collections have special processing for this. 4733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_string_table_.Iterate(v); 4734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kExternalStringsTable); 4736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateSmiRoots(ObjectVisitor* v) { 4740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Acquire execution access since we are going to read stack limit values. 4741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExecutionAccess access(isolate()); 4742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->VisitPointers(&roots_[kSmiRootsStart], &roots_[kRootListLength]); 4743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kSmiRootList); 4744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { 4748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); 4749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kStrongRootList); 4750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->VisitPointer(bit_cast<Object**>(&hidden_string_)); 4752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kInternalizedString); 4753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->bootstrapper()->Iterate(v); 4755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kBootstrapper); 4756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->Iterate(v); 4757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kTop); 4758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Relocatable::Iterate(isolate_, v); 4759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kRelocatable); 4760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (isolate_->deoptimizer_data() != NULL) { 4762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->deoptimizer_data()->Iterate(v); 4763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kDebug); 4765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->compilation_cache()->Iterate(v); 4766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kCompilationCache); 4767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over local handles in handle scopes. 4769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->handle_scope_implementer()->Iterate(v); 4770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->IterateDeferredHandles(v); 4771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kHandleScope); 4772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over the builtin code objects and code stubs in the 4774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // heap. Note that it is not necessary to iterate over code objects 4775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // on scavenge collections. 4776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode != VISIT_ALL_IN_SCAVENGE) { 4777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->builtins()->IterateBuiltins(v); 4778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kBuiltins); 4780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over global handles. 4782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (mode) { 4783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case VISIT_ONLY_STRONG: 4784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->global_handles()->IterateStrongRoots(v); 4785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case VISIT_ALL_IN_SCAVENGE: 4787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v); 4788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case VISIT_ALL_IN_SWEEP_NEWSPACE: 4790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case VISIT_ALL: 4791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->global_handles()->IterateAllRoots(v); 4792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kGlobalHandles); 4795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over eternal handles. 4797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == VISIT_ALL_IN_SCAVENGE) { 4798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->eternal_handles()->IterateNewSpaceRoots(v); 4799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->eternal_handles()->IterateAllRoots(v); 4801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kEternalHandles); 4803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over pointers being held by inactive threads. 4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->thread_manager()->Iterate(v); 4806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v->Synchronize(VisitorSynchronization::kThreadManager); 4807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over the pointers the Serialization/Deserialization code is 4809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // holding. 4810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // During garbage collection this keeps the partial snapshot cache alive. 4811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // During deserialization of the startup snapshot this creates the partial 4812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // snapshot cache and deserializes the objects it refers to. During 4813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // serialization this does nothing, since the partial snapshot cache is 4814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // empty. However the next thing we do is create the partial snapshot, 4815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // filling up the partial snapshot cache with objects it needs as we go. 4816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SerializerDeserializer::Iterate(isolate_, v); 4817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We don't do a v->Synchronize call here, because in debug mode that will 4818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // output a flag to the snapshot. However at this point the serializer and 4819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // deserializer are deliberately a little unsynchronized (see above) so the 4820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // checking of the sync flag in the snapshot would fail. 4821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(1236194): Since the heap size is configurable on the command line 4825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and through the API, we should gracefully handle the case that the heap 4826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// size is not big enough to fit all the initial objects. 4827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::ConfigureHeap(int max_semi_space_size, int max_old_space_size, 4828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int max_executable_size, size_t code_range_size) { 4829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasBeenSetUp()) return false; 4830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Overwrite default configuration. 4832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (max_semi_space_size > 0) { 4833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_semi_space_size_ = max_semi_space_size * MB; 4834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (max_old_space_size > 0) { 4836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_old_generation_size_ = max_old_space_size * MB; 4837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (max_executable_size > 0) { 4839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_executable_size_ = max_executable_size * MB; 4840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If max space size flags are specified overwrite the configuration. 4843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_max_semi_space_size > 0) { 4844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_semi_space_size_ = FLAG_max_semi_space_size * MB; 4845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_max_old_space_size > 0) { 4847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_old_generation_size_ = FLAG_max_old_space_size * MB; 4848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_max_executable_size > 0) { 4850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_executable_size_ = FLAG_max_executable_size * MB; 4851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_stress_compaction) { 4854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This will cause more frequent GCs when stressing. 4855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_semi_space_size_ = Page::kPageSize; 4856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Snapshot::HaveASnapshotToStartFrom()) { 4859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we are using a snapshot we always reserve the default amount 4860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of memory for each semispace because code in the snapshot has 4861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // write-barrier code that relies on the size and alignment of new 4862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // space. We therefore cannot use a larger max semispace size 4863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // than the default reserved semispace size. 4864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (max_semi_space_size_ > reserved_semispace_size_) { 4865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_semi_space_size_ = reserved_semispace_size_; 4866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_gc) { 4867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID("Max semi-space size cannot be more than %d kbytes\n", 4868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reserved_semispace_size_ >> 10); 4869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we are not using snapshots we reserve space for the actual 4873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // max semispace size. 4874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reserved_semispace_size_ = max_semi_space_size_; 4875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The max executable size must be less than or equal to the max old 4878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generation size. 4879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (max_executable_size_ > max_old_generation_size_) { 4880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_executable_size_ = max_old_generation_size_; 4881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The new space size must be a power of two to support single-bit testing 4884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for containment. 4885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_semi_space_size_ = 4886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::bits::RoundUpToPowerOfTwo32(max_semi_space_size_); 4887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reserved_semispace_size_ = 4888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::bits::RoundUpToPowerOfTwo32(reserved_semispace_size_); 4889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_min_semi_space_size > 0) { 4891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int initial_semispace_size = FLAG_min_semi_space_size * MB; 4892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (initial_semispace_size > max_semi_space_size_) { 4893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial_semispace_size_ = max_semi_space_size_; 4894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_gc) { 4895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintPID( 4896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "Min semi-space size cannot be more than the maximum" 4897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "semi-space size of %d MB\n", 4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_semi_space_size_); 4899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial_semispace_size_ = initial_semispace_size; 4902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial_semispace_size_ = Min(initial_semispace_size_, max_semi_space_size_); 4906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The old generation is paged and needs at least one page for each space. 4908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1; 4909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_old_generation_size_ = 4910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Max(static_cast<intptr_t>(paged_space_count * Page::kPageSize), 4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_old_generation_size_); 4912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We rely on being able to allocate new arrays in paged spaces. 4914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Page::kMaxRegularHeapObjectSize >= 4915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (JSArray::kSize + 4916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray::SizeFor(JSObject::kInitialMaxFastElementArray) + 4917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationMemento::kSize)); 4918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_range_size_ = code_range_size * MB; 4920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch configured_ = true; 4922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 4923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::ConfigureHeapDefault() { return ConfigureHeap(0, 0, 0, 0); } 4927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RecordStats(HeapStats* stats, bool take_snapshot) { 4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->start_marker = HeapStats::kStartMarker; 4931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->end_marker = HeapStats::kEndMarker; 4932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->new_space_size = new_space_.SizeAsInt(); 4933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->new_space_capacity = static_cast<int>(new_space_.Capacity()); 4934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->old_pointer_space_size = old_pointer_space_->SizeOfObjects(); 4935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->old_pointer_space_capacity = old_pointer_space_->Capacity(); 4936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->old_data_space_size = old_data_space_->SizeOfObjects(); 4937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->old_data_space_capacity = old_data_space_->Capacity(); 4938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->code_space_size = code_space_->SizeOfObjects(); 4939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->code_space_capacity = code_space_->Capacity(); 4940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->map_space_size = map_space_->SizeOfObjects(); 4941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->map_space_capacity = map_space_->Capacity(); 4942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->cell_space_size = cell_space_->SizeOfObjects(); 4943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->cell_space_capacity = cell_space_->Capacity(); 4944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->property_cell_space_size = property_cell_space_->SizeOfObjects(); 4945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->property_cell_space_capacity = property_cell_space_->Capacity(); 4946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->lo_space_size = lo_space_->Size(); 4947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->global_handles()->RecordStats(stats); 4948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->memory_allocator_size = isolate()->memory_allocator()->Size(); 4949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->memory_allocator_capacity = 4950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->memory_allocator()->Size() + 4951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->memory_allocator()->Available(); 4952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *stats->os_error = base::OS::GetLastError(); 4953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->memory_allocator()->Available(); 4954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (take_snapshot) { 4955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapIterator iterator(this); 4956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HeapObject* obj = iterator.next(); obj != NULL; 4957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj = iterator.next()) { 4958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstanceType type = obj->map()->instance_type(); 4959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(0 <= type && type <= LAST_TYPE); 4960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stats->objects_per_type[type]++; 4961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stats->size_per_type[type] += obj->Size(); 4962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::PromotedSpaceSizeOfObjects() { 4968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return old_pointer_space_->SizeOfObjects() + 4969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->SizeOfObjects() + code_space_->SizeOfObjects() + 4970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->SizeOfObjects() + cell_space_->SizeOfObjects() + 4971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->SizeOfObjects() + lo_space_->SizeOfObjects(); 4972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint64_t Heap::PromotedExternalMemorySize() { 4976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (amount_of_external_allocated_memory_ <= 4977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch amount_of_external_allocated_memory_at_last_global_gc_) 4978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return 0; 4979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return amount_of_external_allocated_memory_ - 4980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch amount_of_external_allocated_memory_at_last_global_gc_; 4981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size, 4985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int freed_global_handles) { 4986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kMaxHandles = 1000; 4987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kMinHandles = 100; 4988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double min_factor = 1.1; 4989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double max_factor = 4; 4990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We set the old generation growing factor to 2 to grow the heap slower on 4991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // memory-constrained devices. 4992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { 4993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_factor = 2; 4994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there are many freed global handles, then the next full GC will 4996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // likely collect a lot of garbage. Choose the heap growing factor 4997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // depending on freed global handles. 4998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(ulan, hpayer): Take into account mutator utilization. 4999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double factor; 5000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (freed_global_handles <= kMinHandles) { 5001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factor = max_factor; 5002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (freed_global_handles >= kMaxHandles) { 5003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factor = min_factor; 5004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute factor using linear interpolation between points 5006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (kMinHandles, max_factor) and (kMaxHandles, min_factor). 5007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factor = max_factor - 5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (freed_global_handles - kMinHandles) * (max_factor - min_factor) / 5009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (kMaxHandles - kMinHandles); 5010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_stress_compaction || 5013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->reduce_memory_footprint_) { 5014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factor = min_factor; 5015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t limit = static_cast<intptr_t>(old_gen_size * factor); 5018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch limit = Max(limit, kMinimumOldGenerationAllocationLimit); 5019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch limit += new_space_.Capacity(); 5020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2; 5021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Min(limit, halfway_to_the_max); 5022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnableInlineAllocation() { 5026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!inline_allocation_disabled_) return; 5027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline_allocation_disabled_ = false; 5028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update inline allocation limit for new space. 5030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space()->UpdateInlineAllocationLimit(0); 5031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::DisableInlineAllocation() { 5035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inline_allocation_disabled_) return; 5036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline_allocation_disabled_ = true; 5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update inline allocation limit for new space. 5039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space()->UpdateInlineAllocationLimit(0); 5040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update inline allocation limit for old spaces. 5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PagedSpaces spaces(this); 5043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (PagedSpace* space = spaces.next(); space != NULL; 5044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space = spaces.next()) { 5045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space->EmptyAllocationInfo(); 5046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochV8_DECLARE_ONCE(initialize_gc_once); 5051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void InitializeGCOnce() { 5053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeScavengingVisitorsTables(); 5054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NewSpaceScavenger::Initialize(); 5055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkCompactCollector::Initialize(); 5056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::SetUp() { 5060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 5061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_timeout_ = FLAG_gc_interval; 5062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 5063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize heap spaces and initial maps and objects. Whenever something 5065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // goes wrong, just return false. The caller should check the results and 5066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // call Heap::TearDown() to release allocated memory. 5067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 5068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the heap is not yet configured (e.g. through the API), configure it. 5069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Configuration is based on the flags new-space-size (really the semispace 5070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // size) and old-space-size if set or the initial values of semispace_size_ 5071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and old_generation_size_ otherwise. 5072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!configured_) { 5073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ConfigureHeapDefault()) return false; 5074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::CallOnce(&initialize_gc_once, &InitializeGCOnce); 5077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkMapPointersAsEncoded(false); 5079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set up memory allocator. 5081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!isolate_->memory_allocator()->SetUp(MaxReserved(), MaxExecutableSize())) 5082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set up new space. 5085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!new_space_.SetUp(reserved_semispace_size_, max_semi_space_size_)) { 5086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_top_after_last_gc_ = new_space()->top(); 5089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize old pointer space. 5091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_ = new OldSpace(this, max_old_generation_size_, 5092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OLD_POINTER_SPACE, NOT_EXECUTABLE); 5093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (old_pointer_space_ == NULL) return false; 5094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!old_pointer_space_->SetUp()) return false; 5095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize old data space. 5097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_ = new OldSpace(this, max_old_generation_size_, OLD_DATA_SPACE, 5098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NOT_EXECUTABLE); 5099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (old_data_space_ == NULL) return false; 5100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!old_data_space_->SetUp()) return false; 5101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!isolate_->code_range()->SetUp(code_range_size_)) return false; 5103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the code space, set its maximum capacity to the old 5105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generation size. It needs executable memory. 5106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_ = 5107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new OldSpace(this, max_old_generation_size_, CODE_SPACE, EXECUTABLE); 5108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_space_ == NULL) return false; 5109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!code_space_->SetUp()) return false; 5110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize map space. 5112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_ = new MapSpace(this, max_old_generation_size_, MAP_SPACE); 5113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map_space_ == NULL) return false; 5114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!map_space_->SetUp()) return false; 5115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize simple cell space. 5117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_ = new CellSpace(this, max_old_generation_size_, CELL_SPACE); 5118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cell_space_ == NULL) return false; 5119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!cell_space_->SetUp()) return false; 5120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize global property cell space. 5122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_ = new PropertyCellSpace(this, max_old_generation_size_, 5123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROPERTY_CELL_SPACE); 5124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (property_cell_space_ == NULL) return false; 5125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!property_cell_space_->SetUp()) return false; 5126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The large object code space may contain code or data. We set the memory 5128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to be non-executable here for safety, but this means we need to enable it 5129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // explicitly when allocating large code objects. 5130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_ = new LargeObjectSpace(this, max_old_generation_size_, LO_SPACE); 5131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (lo_space_ == NULL) return false; 5132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!lo_space_->SetUp()) return false; 5133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set up the seed that is used to randomize the string hash function. 5135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(hash_seed() == 0); 5136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_randomize_hashes) { 5137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hash_seed == 0) { 5138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int rnd = isolate()->random_number_generator()->NextInt(); 5139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_hash_seed(Smi::FromInt(rnd & Name::kHashBitMask)); 5140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_hash_seed(Smi::FromInt(FLAG_hash_seed)); 5142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity())); 5146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG(isolate_, IntPtrTEvent("heap-available", Available())); 5147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer()->SetUp(); 5149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->SetUp(); 5151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 5153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CreateHeapObjects() { 5157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create initial maps. 5158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CreateInitialMaps()) return false; 5159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateApiObjects(); 5160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create initial objects 5162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateInitialObjects(); 5163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, gc_count_); 5164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_native_contexts_list(undefined_value()); 5166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_array_buffers_list(undefined_value()); 5167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_allocation_sites_list(undefined_value()); 5168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch weak_object_to_code_table_ = undefined_value(); 5169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 5170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::SetStackLimits() { 5174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(isolate_ != NULL); 5175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(isolate_ == isolate()); 5176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On 64 bit machines, pointers are generally out of range of Smis. We write 5177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // something that looks like an out of range Smi to the GC. 5178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set up the special root array entries containing the stack limits. 5180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // These are actually addresses, but the tag makes the GC ignore it. 5181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch roots_[kStackLimitRootIndex] = reinterpret_cast<Object*>( 5182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag); 5183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch roots_[kRealStackLimitRootIndex] = reinterpret_cast<Object*>( 5184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag); 5185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TearDown() { 5189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 5190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_heap) { 5191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Verify(); 5192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 5194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateMaximumCommitted(); 5196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_print_cumulative_gc_stat) { 5198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 5199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("gc_count=%d ", gc_count_); 5200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("mark_sweep_count=%d ", ms_count_); 5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("max_gc_pause=%.1f ", get_max_gc_pause()); 5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("total_gc_time=%.1f ", total_gc_time_ms_); 5203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("min_in_mutator=%.1f ", get_min_in_mutator()); 5204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", get_max_alive_after_gc()); 5205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("total_marking_time=%.1f ", tracer_.cumulative_sweeping_duration()); 5206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("total_sweeping_time=%.1f ", tracer_.cumulative_sweeping_duration()); 5207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n\n"); 5208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_print_max_heap_committed) { 5211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 5212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_heap=%" V8_PTR_PREFIX "d ", 5213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MaximumCommittedMemory()); 5214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_new_space=%" V8_PTR_PREFIX "d ", 5215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.MaximumCommittedMemory()); 5216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_old_pointer_space=%" V8_PTR_PREFIX "d ", 5217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->MaximumCommittedMemory()); 5218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_old_data_space=%" V8_PTR_PREFIX "d ", 5219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->MaximumCommittedMemory()); 5220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_old_data_space=%" V8_PTR_PREFIX "d ", 5221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->MaximumCommittedMemory()); 5222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_code_space=%" V8_PTR_PREFIX "d ", 5223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_->MaximumCommittedMemory()); 5224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_map_space=%" V8_PTR_PREFIX "d ", 5225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->MaximumCommittedMemory()); 5226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_cell_space=%" V8_PTR_PREFIX "d ", 5227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_->MaximumCommittedMemory()); 5228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_property_space=%" V8_PTR_PREFIX "d ", 5229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->MaximumCommittedMemory()); 5230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("maximum_committed_by_lo_space=%" V8_PTR_PREFIX "d ", 5231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_->MaximumCommittedMemory()); 5232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n\n"); 5233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_predictable) { 5236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintAlloctionsHash(); 5237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TearDownArrayBuffers(); 5240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->global_handles()->TearDown(); 5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_string_table_.TearDown(); 5244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_compact_collector()->TearDown(); 5246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_.TearDown(); 5248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (old_pointer_space_ != NULL) { 5250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_->TearDown(); 5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete old_pointer_space_; 5252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_pointer_space_ = NULL; 5253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (old_data_space_ != NULL) { 5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_->TearDown(); 5257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete old_data_space_; 5258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_data_space_ = NULL; 5259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_space_ != NULL) { 5262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_->TearDown(); 5263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete code_space_; 5264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_space_ = NULL; 5265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map_space_ != NULL) { 5268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_->TearDown(); 5269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete map_space_; 5270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_space_ = NULL; 5271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cell_space_ != NULL) { 5274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_->TearDown(); 5275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete cell_space_; 5276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cell_space_ = NULL; 5277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (property_cell_space_ != NULL) { 5280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_->TearDown(); 5281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete property_cell_space_; 5282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch property_cell_space_ = NULL; 5283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (lo_space_ != NULL) { 5286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_->TearDown(); 5287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete lo_space_; 5288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lo_space_ = NULL; 5289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_buffer()->TearDown(); 5292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incremental_marking()->TearDown(); 5293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->memory_allocator()->TearDown(); 5295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::AddGCPrologueCallback(v8::Isolate::GCPrologueCallback callback, 5299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCType gc_type, bool pass_isolate) { 5300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(callback != NULL); 5301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCPrologueCallbackPair pair(callback, gc_type, pass_isolate); 5302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!gc_prologue_callbacks_.Contains(pair)); 5303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return gc_prologue_callbacks_.Add(pair); 5304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RemoveGCPrologueCallback(v8::Isolate::GCPrologueCallback callback) { 5308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(callback != NULL); 5309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) { 5310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (gc_prologue_callbacks_[i].callback == callback) { 5311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_prologue_callbacks_.Remove(i); 5312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 5313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 5316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::AddGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback, 5320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCType gc_type, bool pass_isolate) { 5321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(callback != NULL); 5322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GCEpilogueCallbackPair pair(callback, gc_type, pass_isolate); 5323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!gc_epilogue_callbacks_.Contains(pair)); 5324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return gc_epilogue_callbacks_.Add(pair); 5325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RemoveGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback) { 5329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(callback != NULL); 5330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { 5331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (gc_epilogue_callbacks_[i].callback == callback) { 5332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_epilogue_callbacks_.Remove(i); 5333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 5334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 5337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(ishell): Find a better place for this. 5341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::AddWeakObjectToCodeDependency(Handle<Object> obj, 5342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<DependentCode> dep) { 5343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!InNewSpace(*obj)); 5344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!InNewSpace(*dep)); 5345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This handle scope keeps the table handle local to this function, which 5346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allows us to safely skip write barriers in table update operations. 5347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate()); 5348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<WeakHashTable> table(WeakHashTable::cast(weak_object_to_code_table_), 5349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()); 5350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table = WeakHashTable::Put(table, obj, dep); 5351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ShouldZapGarbage() && weak_object_to_code_table_ != *table) { 5353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WeakHashTable::cast(weak_object_to_code_table_)->Zap(the_hole_value()); 5354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_weak_object_to_code_table(*table); 5356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(*dep, table->Lookup(obj)); 5357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDependentCode* Heap::LookupWeakObjectToCodeDependency(Handle<Object> obj) { 5361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* dep = WeakHashTable::cast(weak_object_to_code_table_)->Lookup(obj); 5362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dep->IsDependentCode()) return DependentCode::cast(dep); 5363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return DependentCode::cast(empty_fixed_array()); 5364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnsureWeakObjectToCodeTable() { 5368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!weak_object_to_code_table()->IsHashTable()) { 5369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_weak_object_to_code_table( 5370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *WeakHashTable::New(isolate(), 16, USE_DEFAULT_MINIMUM_CAPACITY, 5371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TENURED)); 5372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::FatalProcessOutOfMemory(const char* location, bool take_snapshot) { 5377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::V8::FatalProcessOutOfMemory(location, take_snapshot); 5378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 5381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PrintHandleVisitor : public ObjectVisitor { 5383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 5384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitPointers(Object** start, Object** end) { 5385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; p < end; p++) 5386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(" handle %p to %p\n", reinterpret_cast<void*>(p), 5387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<void*>(*p)); 5388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 5390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::PrintHandles() { 5393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Handles:\n"); 5394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintHandleVisitor v; 5395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->handle_scope_implementer()->Iterate(&v); 5396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 5399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpace* AllSpaces::next() { 5402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (counter_++) { 5403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NEW_SPACE: 5404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->new_space(); 5405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_POINTER_SPACE: 5406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->old_pointer_space(); 5407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_DATA_SPACE: 5408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->old_data_space(); 5409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CODE_SPACE: 5410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->code_space(); 5411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case MAP_SPACE: 5412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->map_space(); 5413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CELL_SPACE: 5414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->cell_space(); 5415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case PROPERTY_CELL_SPACE: 5416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->property_cell_space(); 5417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LO_SPACE: 5418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->lo_space(); 5419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 5420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 5421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPagedSpace* PagedSpaces::next() { 5426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (counter_++) { 5427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_POINTER_SPACE: 5428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->old_pointer_space(); 5429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_DATA_SPACE: 5430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->old_data_space(); 5431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CODE_SPACE: 5432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->code_space(); 5433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case MAP_SPACE: 5434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->map_space(); 5435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CELL_SPACE: 5436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->cell_space(); 5437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case PROPERTY_CELL_SPACE: 5438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->property_cell_space(); 5439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 5440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 5441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOldSpace* OldSpaces::next() { 5446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (counter_++) { 5447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_POINTER_SPACE: 5448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->old_pointer_space(); 5449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_DATA_SPACE: 5450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->old_data_space(); 5451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CODE_SPACE: 5452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return heap_->code_space(); 5453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 5454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 5455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpaceIterator::SpaceIterator(Heap* heap) 5460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : heap_(heap), 5461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_space_(FIRST_SPACE), 5462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_(NULL), 5463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_func_(NULL) {} 5464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpaceIterator::SpaceIterator(Heap* heap, HeapObjectCallback size_func) 5467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : heap_(heap), 5468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_space_(FIRST_SPACE), 5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_(NULL), 5470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_func_(size_func) {} 5471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpaceIterator::~SpaceIterator() { 5474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Delete active iterator if any. 5475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete iterator_; 5476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool SpaceIterator::has_next() { 5480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate until no more spaces. 5481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return current_space_ != LAST_SPACE; 5482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObjectIterator* SpaceIterator::next() { 5486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (iterator_ != NULL) { 5487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete iterator_; 5488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_ = NULL; 5489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move to the next space 5490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_space_++; 5491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_space_ > LAST_SPACE) { 5492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 5493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return iterator for the new current space. 5497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CreateIterator(); 5498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Create an iterator for the space to iterate. 5502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObjectIterator* SpaceIterator::CreateIterator() { 5503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(iterator_ == NULL); 5504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (current_space_) { 5506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NEW_SPACE: 5507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_ = new SemiSpaceIterator(heap_->new_space(), size_func_); 5508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_POINTER_SPACE: 5510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_ = 5511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new HeapObjectIterator(heap_->old_pointer_space(), size_func_); 5512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case OLD_DATA_SPACE: 5514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_ = new HeapObjectIterator(heap_->old_data_space(), size_func_); 5515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CODE_SPACE: 5517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_ = new HeapObjectIterator(heap_->code_space(), size_func_); 5518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case MAP_SPACE: 5520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_ = new HeapObjectIterator(heap_->map_space(), size_func_); 5521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CELL_SPACE: 5523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_ = new HeapObjectIterator(heap_->cell_space(), size_func_); 5524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case PROPERTY_CELL_SPACE: 5526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_ = 5527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new HeapObjectIterator(heap_->property_cell_space(), size_func_); 5528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LO_SPACE: 5530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator_ = new LargeObjectIterator(heap_->lo_space(), size_func_); 5531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the newly allocated iterator; 5535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(iterator_ != NULL); 5536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return iterator_; 5537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapObjectsFilter { 5541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 5542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~HeapObjectsFilter() {} 5543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual bool SkipObject(HeapObject* object) = 0; 5544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 5545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass UnreachableObjectsFilter : public HeapObjectsFilter { 5548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 5549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) { 5550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkReachableObjects(); 5551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~UnreachableObjectsFilter() { 5554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_->mark_compact_collector()->ClearMarkbits(); 5555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool SkipObject(HeapObject* object) { 5558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit mark_bit = Marking::MarkBitFrom(object); 5559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !mark_bit.Get(); 5560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 5563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class MarkingVisitor : public ObjectVisitor { 5564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 5565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingVisitor() : marking_stack_(10) {} 5566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitPointers(Object** start, Object** end) { 5568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; p < end; p++) { 5569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!(*p)->IsHeapObject()) continue; 5570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj = HeapObject::cast(*p); 5571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkBit mark_bit = Marking::MarkBitFrom(obj); 5572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!mark_bit.Get()) { 5573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_bit.Set(); 5574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch marking_stack_.Add(obj); 5575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TransitiveClosure() { 5580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!marking_stack_.is_empty()) { 5581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj = marking_stack_.RemoveLast(); 5582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->Iterate(this); 5583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 5587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<HeapObject*> marking_stack_; 5588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 5589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkReachableObjects() { 5591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkingVisitor visitor; 5592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_->IterateRoots(&visitor, VISIT_ALL); 5593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor.TransitiveClosure(); 5594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 5597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation_; 5598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 5599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapIterator::HeapIterator(Heap* heap) 5602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : make_heap_iterable_helper_(heap), 5603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_heap_allocation_(), 5604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_(heap), 5605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filtering_(HeapIterator::kNoFiltering), 5606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filter_(NULL) { 5607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Init(); 5608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapIterator::HeapIterator(Heap* heap, 5612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapIterator::HeapObjectsFiltering filtering) 5613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : make_heap_iterable_helper_(heap), 5614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_heap_allocation_(), 5615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_(heap), 5616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filtering_(filtering), 5617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filter_(NULL) { 5618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Init(); 5619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapIterator::~HeapIterator() { Shutdown(); } 5623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HeapIterator::Init() { 5626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Start the iteration. 5627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space_iterator_ = new SpaceIterator(heap_); 5628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (filtering_) { 5629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kFilterUnreachable: 5630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filter_ = new UnreachableObjectsFilter(heap_); 5631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 5633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_iterator_ = space_iterator_->next(); 5636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HeapIterator::Shutdown() { 5640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 5641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Assert that in filtering mode we have iterated through all 5642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // objects. Otherwise, heap will be left in an inconsistent state. 5643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (filtering_ != kNoFiltering) { 5644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object_iterator_ == NULL); 5645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 5647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure the last iterator is deallocated. 5648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete space_iterator_; 5649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space_iterator_ = NULL; 5650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_iterator_ = NULL; 5651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete filter_; 5652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch filter_ = NULL; 5653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapObject* HeapIterator::next() { 5657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (filter_ == NULL) return NextObject(); 5658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj = NextObject(); 5660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (obj != NULL && filter_->SkipObject(obj)) obj = NextObject(); 5661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return obj; 5662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapObject* HeapIterator::NextObject() { 5666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No iterator means we are done. 5667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object_iterator_ == NULL) return NULL; 5668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HeapObject* obj = object_iterator_->next_object()) { 5670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the current iterator has more objects we are fine. 5671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return obj; 5672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Go though the spaces looking for one that has objects. 5674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (space_iterator_->has_next()) { 5675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_iterator_ = space_iterator_->next(); 5676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HeapObject* obj = object_iterator_->next_object()) { 5677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return obj; 5678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Done with the last space. 5682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_iterator_ = NULL; 5683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 5684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HeapIterator::reset() { 5688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restart the iterator. 5689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Shutdown(); 5690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Init(); 5691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 5695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject* const PathTracer::kAnyGlobalObject = NULL; 5697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PathTracer::MarkVisitor : public ObjectVisitor { 5699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 5700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit MarkVisitor(PathTracer* tracer) : tracer_(tracer) {} 5701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitPointers(Object** start, Object** end) { 5702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Scan all HeapObject pointers in [start, end) 5703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; !tracer_->found() && (p < end); p++) { 5704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*p)->IsHeapObject()) tracer_->MarkRecursively(p, this); 5705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 5709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PathTracer* tracer_; 5710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 5711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PathTracer::UnmarkVisitor : public ObjectVisitor { 5714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 5715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit UnmarkVisitor(PathTracer* tracer) : tracer_(tracer) {} 5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitPointers(Object** start, Object** end) { 5717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Scan all HeapObject pointers in [start, end) 5718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; p < end; p++) { 5719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*p)->IsHeapObject()) tracer_->UnmarkRecursively(p, this); 5720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PathTracer* tracer_; 5725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 5726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::VisitPointers(Object** start, Object** end) { 5729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool done = ((what_to_find_ == FIND_FIRST) && found_target_); 5730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit all HeapObject pointers in [start, end) 5731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (Object** p = start; !done && (p < end); p++) { 5732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*p)->IsHeapObject()) { 5733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TracePathFrom(p); 5734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch done = ((what_to_find_ == FIND_FIRST) && found_target_); 5735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::Reset() { 5741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_target_ = false; 5742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_stack_.Clear(); 5743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::TracePathFrom(Object** root) { 5747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((search_target_ == kAnyGlobalObject) || 5748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch search_target_->IsHeapObject()); 5749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_target_in_trace_ = false; 5750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Reset(); 5751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkVisitor mark_visitor(this); 5753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkRecursively(root, &mark_visitor); 5754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnmarkVisitor unmark_visitor(this); 5756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnmarkRecursively(root, &unmark_visitor); 5757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessResults(); 5759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool SafeIsNativeContext(HeapObject* obj) { 5763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return obj->map() == obj->GetHeap()->raw_unchecked_native_context_map(); 5764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) { 5768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!(*p)->IsHeapObject()) return; 5769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj = HeapObject::cast(*p); 5771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord map_word = obj->map_word(); 5773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!map_word.ToMap()->IsHeapObject()) return; // visited before 5774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (found_target_in_trace_) return; // stop if target found 5776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_stack_.Add(obj); 5777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (((search_target_ == kAnyGlobalObject) && obj->IsJSGlobalObject()) || 5778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (obj == search_target_)) { 5779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_target_in_trace_ = true; 5780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_target_ = true; 5781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 5782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_native_context = SafeIsNativeContext(obj); 5785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // not visited yet 5787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map = Map::cast(map_word.ToMap()); 5788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord marked_map_word = 5790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord::FromRawValue(obj->map_word().ToRawValue() + kMarkTag); 5791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->set_map_word(marked_map_word); 5792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Scan the object body. 5794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_native_context && (visit_mode_ == VISIT_ONLY_STRONG)) { 5795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is specialized to scan Context's properly. 5796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** start = 5797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Object**>(obj->address() + Context::kHeaderSize); 5798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object** end = 5799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Object**>(obj->address() + Context::kHeaderSize + 5800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Context::FIRST_WEAK_SLOT * kPointerSize); 5801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mark_visitor->VisitPointers(start, end); 5802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->IterateBody(map->instance_type(), obj->SizeFromMap(map), mark_visitor); 5804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Scan the map after the body because the body is a lot more interesting 5807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // when doing leak detection. 5808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkRecursively(reinterpret_cast<Object**>(&map), mark_visitor); 5809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!found_target_in_trace_) { // don't pop if found the target 5811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_stack_.RemoveLast(); 5812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::UnmarkRecursively(Object** p, UnmarkVisitor* unmark_visitor) { 5817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!(*p)->IsHeapObject()) return; 5818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* obj = HeapObject::cast(*p); 5820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord map_word = obj->map_word(); 5822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map_word.ToMap()->IsHeapObject()) return; // unmarked already 5823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord unmarked_map_word = 5825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapWord::FromRawValue(map_word.ToRawValue() - kMarkTag); 5826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->set_map_word(unmarked_map_word); 5827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map = Map::cast(unmarked_map_word.ToMap()); 5829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnmarkRecursively(reinterpret_cast<Object**>(&map), unmark_visitor); 5831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->IterateBody(map->instance_type(), obj->SizeFromMap(map), unmark_visitor); 5833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::ProcessResults() { 5837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (found_target_) { 5838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 5839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "=====================================\n" 5840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch << "==== Path to object ====\n" 5841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch << "=====================================\n\n"; 5842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object_stack_.is_empty()); 5844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < object_stack_.length(); i++) { 5845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i > 0) os << "\n |\n |\n V\n\n"; 5846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_stack_[i]->Print(os); 5847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "=====================================\n"; 5849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Triggers a depth-first traversal of reachable objects from one 5854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// given root object and finds a path to a specific heap object and 5855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// prints it. 5856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TracePathToObjectFrom(Object* target, Object* root) { 5857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL); 5858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracer.VisitPointer(&root); 5859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Triggers a depth-first traversal of reachable objects from roots 5863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and finds a path to a specific heap object and prints it. 5864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TracePathToObject(Object* target) { 5865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL); 5866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterateRoots(&tracer, VISIT_ONLY_STRONG); 5867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Triggers a depth-first traversal of reachable objects from roots 5871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and finds a path to any global object and prints it. Useful for 5872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// determining the source for leaks of global objects. 5873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TracePathToGlobal() { 5874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PathTracer tracer(PathTracer::kAnyGlobalObject, PathTracer::FIND_ALL, 5875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VISIT_ALL); 5876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterateRoots(&tracer, VISIT_ONLY_STRONG); 5877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 5879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateCumulativeGCStatistics(double duration, 5882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double spent_in_mutator, 5883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double marking_time) { 5884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_print_cumulative_gc_stat) { 5885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_gc_time_ms_ += duration; 5886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_gc_pause_ = Max(max_gc_pause_, duration); 5887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_alive_after_gc_ = Max(max_alive_after_gc_, SizeOfObjects()); 5888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch min_in_mutator_ = Min(min_in_mutator_, spent_in_mutator); 5889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (FLAG_trace_gc_verbose) { 5890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_gc_time_ms_ += duration; 5891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch marking_time_ += marking_time; 5894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint KeyedLookupCache::Hash(Handle<Map> map, Handle<Name> name) { 5898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 5899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Uses only lower 32 bits if pointers are larger. 5900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uintptr_t addr_hash = 5901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<uint32_t>(reinterpret_cast<uintptr_t>(*map)) >> kMapHashShift; 5902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask); 5903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint KeyedLookupCache::Lookup(Handle<Map> map, Handle<Name> name) { 5907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 5908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = (Hash(map, name) & kHashMask); 5909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kEntriesPerBucket; i++) { 5910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Key& key = keys_[index + i]; 5911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((key.map == *map) && key.name->Equals(*name)) { 5912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return field_offsets_[index + i]; 5913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotFound; 5916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid KeyedLookupCache::Update(Handle<Map> map, Handle<Name> name, 5920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int field_offset) { 5921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 5922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!name->IsUniqueName()) { 5923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!StringTable::InternalizeStringIfExists( 5924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name->GetIsolate(), Handle<String>::cast(name)).ToHandle(&name)) { 5925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 5926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This cache is cleared only between mark compact passes, so we expect the 5929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // cache to only contain old space names. 5930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!map->GetIsolate()->heap()->InNewSpace(*name)); 5931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = (Hash(map, name) & kHashMask); 5933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After a GC there will be free slots, so we use them in order (this may 5934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // help to get the most frequently used one in position 0). 5935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kEntriesPerBucket; i++) { 5936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Key& key = keys_[index]; 5937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* free_entry_indicator = NULL; 5938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (key.map == free_entry_indicator) { 5939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key.map = *map; 5940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key.name = *name; 5941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_offsets_[index + i] = field_offset; 5942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 5943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No free entry found in this bucket, so we move them all down one and 5946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // put the new entry at position zero. 5947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = kEntriesPerBucket - 1; i > 0; i--) { 5948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Key& key = keys_[index + i]; 5949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Key& key2 = keys_[index + i - 1]; 5950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = key2; 5951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_offsets_[index + i] = field_offsets_[index + i - 1]; 5952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Write the new first entry. 5955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Key& key = keys_[index]; 5956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key.map = *map; 5957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key.name = *name; 5958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_offsets_[index] = field_offset; 5959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid KeyedLookupCache::Clear() { 5963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int index = 0; index < kLength; index++) keys_[index].map = NULL; 5964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DescriptorLookupCache::Clear() { 5968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int index = 0; index < kLength; index++) keys_[index].source = NULL; 5969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ExternalStringTable::CleanUp() { 5973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int last = 0; 5974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < new_space_strings_.length(); ++i) { 5975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (new_space_strings_[i] == heap_->the_hole_value()) { 5976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 5977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(new_space_strings_[i]->IsExternalString()); 5979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (heap_->InNewSpace(new_space_strings_[i])) { 5980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_strings_[last++] = new_space_strings_[i]; 5981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_space_strings_.Add(new_space_strings_[i]); 5983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_strings_.Rewind(last); 5986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_strings_.Trim(); 5987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last = 0; 5989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < old_space_strings_.length(); ++i) { 5990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (old_space_strings_[i] == heap_->the_hole_value()) { 5991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 5992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(old_space_strings_[i]->IsExternalString()); 5994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!heap_->InNewSpace(old_space_strings_[i])); 5995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_space_strings_[last++] = old_space_strings_[i]; 5996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_space_strings_.Rewind(last); 5998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_space_strings_.Trim(); 5999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 6000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_verify_heap) { 6001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Verify(); 6002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 6004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ExternalStringTable::TearDown() { 6008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < new_space_strings_.length(); ++i) { 6009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i])); 6010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_space_strings_.Free(); 6012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < old_space_strings_.length(); ++i) { 6013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i])); 6014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_space_strings_.Free(); 6016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { 6020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk->set_next_chunk(chunks_queued_for_free_); 6021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunks_queued_for_free_ = chunk; 6022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::FreeQueuedChunks() { 6026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (chunks_queued_for_free_ == NULL) return; 6027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk* next; 6028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk* chunk; 6029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { 6030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next = chunk->next_chunk(); 6031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED); 6032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (chunk->owner()->identity() == LO_SPACE) { 6034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // StoreBuffer::Filter relies on MemoryChunk::FromAnyPointerAddress. 6035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If FromAnyPointerAddress encounters a slot that belongs to a large 6036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chunk queued for deletion it will fail to find the chunk because 6037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it try to perform a search in the list of pages owned by of the large 6038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object space and queued chunks were detached from that list. 6039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // To work around this we split large chunk into normal kPageSize aligned 6040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pieces and initialize size, owner and flags field of every piece. 6041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If FromAnyPointerAddress encounters a slot that belongs to one of 6042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // these smaller pieces it will treat it as a slot on a normal Page. 6043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address chunk_end = chunk->address() + chunk->size(); 6044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk* inner = 6045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::FromAddress(chunk->address() + Page::kPageSize); 6046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk* inner_last = MemoryChunk::FromAddress(chunk_end - 1); 6047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (inner <= inner_last) { 6048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of a large chunk is always a multiple of 6049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // OS::AllocateAlignment() so there is always 6050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // enough space for a fake MemoryChunk header. 6051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address area_end = Min(inner->address() + Page::kPageSize, chunk_end); 6052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Guard against overflow. 6053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (area_end < inner->address()) area_end = chunk_end; 6054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner->SetArea(inner->address(), area_end); 6055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner->set_size(Page::kPageSize); 6056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner->set_owner(lo_space()); 6057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED); 6058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner = MemoryChunk::FromAddress(inner->address() + Page::kPageSize); 6059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->heap()->store_buffer()->Compact(); 6063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); 6064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { 6065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next = chunk->next_chunk(); 6066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->memory_allocator()->Free(chunk); 6067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunks_queued_for_free_ = NULL; 6069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RememberUnmappedPage(Address page, bool compacted) { 6073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uintptr_t p = reinterpret_cast<uintptr_t>(page); 6074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Tag the page pointer to make it findable in the dump file. 6075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (compacted) { 6076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p ^= 0xc1ead & (Page::kPageSize - 1); // Cleared. 6077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. 6079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch remembered_unmapped_pages_[remembered_unmapped_pages_index_] = 6081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Address>(p); 6082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch remembered_unmapped_pages_index_++; 6083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch remembered_unmapped_pages_index_ %= kRememberedUnmappedPages; 6084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ClearObjectStats(bool clear_last_time_stats) { 6088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memset(object_counts_, 0, sizeof(object_counts_)); 6089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memset(object_sizes_, 0, sizeof(object_sizes_)); 6090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (clear_last_time_stats) { 6091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memset(object_counts_last_time_, 0, sizeof(object_counts_last_time_)); 6092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memset(object_sizes_last_time_, 0, sizeof(object_sizes_last_time_)); 6093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic base::LazyMutex checkpoint_object_stats_mutex = LAZY_MUTEX_INITIALIZER; 6098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CheckpointObjectStats() { 6101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::LockGuard<base::Mutex> lock_guard( 6102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checkpoint_object_stats_mutex.Pointer()); 6103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Counters* counters = isolate()->counters(); 6104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \ 6105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->count_of_##name()->Increment( \ 6106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_counts_[name])); \ 6107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->count_of_##name()->Decrement( \ 6108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_counts_last_time_[name])); \ 6109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->size_of_##name()->Increment( \ 6110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_sizes_[name])); \ 6111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->size_of_##name()->Decrement( \ 6112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_sizes_last_time_[name])); 6113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) 6114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ADJUST_LAST_TIME_OBJECT_COUNT 6115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index; 6116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \ 6117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index = FIRST_CODE_KIND_SUB_TYPE + Code::name; \ 6118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->count_of_CODE_TYPE_##name()->Increment( \ 6119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_counts_[index])); \ 6120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->count_of_CODE_TYPE_##name()->Decrement( \ 6121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_counts_last_time_[index])); \ 6122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->size_of_CODE_TYPE_##name()->Increment( \ 6123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_sizes_[index])); \ 6124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->size_of_CODE_TYPE_##name()->Decrement( \ 6125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_sizes_last_time_[index])); 6126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CODE_KIND_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) 6127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ADJUST_LAST_TIME_OBJECT_COUNT 6128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \ 6129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index = FIRST_FIXED_ARRAY_SUB_TYPE + name; \ 6130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->count_of_FIXED_ARRAY_##name()->Increment( \ 6131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_counts_[index])); \ 6132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->count_of_FIXED_ARRAY_##name()->Decrement( \ 6133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_counts_last_time_[index])); \ 6134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->size_of_FIXED_ARRAY_##name()->Increment( \ 6135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_sizes_[index])); \ 6136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->size_of_FIXED_ARRAY_##name()->Decrement( \ 6137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_sizes_last_time_[index])); 6138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) 6139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ADJUST_LAST_TIME_OBJECT_COUNT 6140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \ 6141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index = \ 6142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge; \ 6143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->count_of_CODE_AGE_##name()->Increment( \ 6144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_counts_[index])); \ 6145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->count_of_CODE_AGE_##name()->Decrement( \ 6146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_counts_last_time_[index])); \ 6147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->size_of_CODE_AGE_##name()->Increment( \ 6148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_sizes_[index])); \ 6149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counters->size_of_CODE_AGE_##name()->Decrement( \ 6150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(object_sizes_last_time_[index])); 6151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ADJUST_LAST_TIME_OBJECT_COUNT 6153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearObjectStats(); 6157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8::internal 6160