12efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met:
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions of source code must retain the above copyright
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       notice, this list of conditions and the following disclaimer.
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions in binary form must reproduce the above
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       copyright notice, this list of conditions and the following
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       disclaimer in the documentation and/or other materials provided
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       with the distribution.
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Neither the name of Google Inc. nor the names of its
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       contributors may be used to endorse or promote products derived
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       from this software without specific prior written permission.
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h"
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "accessors.h"
3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "api.h"
3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "bootstrapper.h"
3344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "codegen.h"
34b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org#include "compilation-cache.h"
35c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "cpu-profiler.h"
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "debug.h"
374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#include "deoptimizer.h"
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "global-handles.h"
39fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org#include "heap-profiler.h"
40c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "incremental-marking.h"
4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "mark-compact.h"
4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "natives.h"
43ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org#include "objects-visiting.h"
44c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "objects-visiting-inl.h"
457d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org#include "once.h"
46a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "runtime-profiler.h"
4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "scopeinfo.h"
483811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#include "snapshot.h"
49c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "store-buffer.h"
5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8threads.h"
5156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org#include "v8utils.h"
52a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "vm-state-inl.h"
53c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
5418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#include "regexp-macro-assembler.h"
553811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#include "arm/regexp-macro-assembler-arm.h"
5618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif
577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#if V8_TARGET_ARCH_MIPS && !V8_INTERPRETED_REGEXP
587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#include "regexp-macro-assembler.h"
597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#include "mips/regexp-macro-assembler-mips.h"
607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#endif
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
6371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
657276f14ca716596e0a0d17539516370c1f453847kasper.lund
66ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgHeap::Heap()
67ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    : isolate_(NULL),
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// semispace_size_ should be a power of 2 and old_generation_size_ should be
6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// a multiple of Page::kPageSize.
7093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64
71c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#define LUMP_OF_MEMORY (2 * MB)
72ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      code_range_size_(512*MB),
734a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#else
74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#define LUMP_OF_MEMORY MB
75ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      code_range_size_(0),
764a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#endif
77bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org#if defined(ANDROID) || V8_TARGET_ARCH_MIPS
787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      reserved_semispace_size_(4 * Max(LUMP_OF_MEMORY, Page::kPageSize)),
797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      max_semispace_size_(4 * Max(LUMP_OF_MEMORY, Page::kPageSize)),
807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      initial_semispace_size_(Page::kPageSize),
817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      max_old_generation_size_(192*MB),
827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      max_executable_size_(max_old_generation_size_),
837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org#else
84c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      reserved_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)),
85c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      max_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)),
8664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      initial_semispace_size_(Page::kPageSize),
87c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      max_old_generation_size_(700ul * LUMP_OF_MEMORY),
882c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      max_executable_size_(256l * LUMP_OF_MEMORY),
897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org#endif
90c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Variables set based on semispace_size_ and old_generation_size_ in
92ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_)
933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// Will be 4 * reserved_semispace_size_ to ensure that young
943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// generation can be aligned to its size.
95ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      survived_since_last_expansion_(0),
96ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      sweep_generation_(0),
97ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      always_allocate_scope_depth_(0),
98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      linear_allocation_scope_depth_(0),
99ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      contexts_disposed_(0),
10088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      global_ic_age_(0),
101c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org      flush_monomorphic_ics_(false),
102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      scan_on_scavenge_pages_(0),
103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      new_space_(this),
104ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      old_pointer_space_(NULL),
105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      old_data_space_(NULL),
106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      code_space_(NULL),
107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      map_space_(NULL),
108ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      cell_space_(NULL),
10941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      property_cell_space_(NULL),
110ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      lo_space_(NULL),
111ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      gc_state_(NOT_IN_GC),
112d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      gc_post_processing_depth_(0),
113ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      ms_count_(0),
114ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      gc_count_(0),
1152c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      remembered_unmapped_pages_index_(0),
116ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      unflattened_strings_length_(0),
1177276f14ca716596e0a0d17539516370c1f453847kasper.lund#ifdef DEBUG
118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      allocation_timeout_(0),
119ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      disallow_allocation_failure_(false),
12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // DEBUG
1211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      new_space_high_promotion_mode_active_(false),
122a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit),
123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      size_of_old_gen_at_last_old_space_gc_(0),
124ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      external_allocation_limit_(0),
125ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      amount_of_external_allocated_memory_(0),
126ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      amount_of_external_allocated_memory_at_last_global_gc_(0),
127ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      old_gen_exhausted_(false),
128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      store_buffer_rebuilder_(store_buffer()),
1294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      hidden_string_(NULL),
130ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      global_gc_prologue_callback_(NULL),
131ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      global_gc_epilogue_callback_(NULL),
132ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      gc_safe_size_of_old_object_(NULL),
1337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      total_regexp_code_generated_(0),
134ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      tracer_(NULL),
135ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      young_survivors_after_last_gc_(0),
136ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      high_survival_rate_period_length_(0),
137fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      low_survival_rate_period_length_(0),
138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      survival_rate_(0),
139ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      previous_survival_rate_trend_(Heap::STABLE),
140ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      survival_rate_trend_(Heap::STABLE),
141c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      max_gc_pause_(0.0),
142c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      total_gc_time_ms_(0.0),
143ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      max_alive_after_gc_(0),
144ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      min_in_mutator_(kMaxInt),
145ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      alive_after_last_gc_(0),
146ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      last_gc_end_timestamp_(0.0),
147e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org      marking_time_(0.0),
148e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org      sweeping_time_(0.0),
149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      store_buffer_(this),
150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      marking_(this),
151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      incremental_marking_(this),
152ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      number_idle_notifications_(0),
153ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      last_idle_notification_gc_count_(0),
154ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      last_idle_notification_gc_count_init_(false),
155ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org      mark_sweeps_since_idle_round_started_(0),
156ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org      gc_count_at_last_idle_gc_(0),
157ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org      scavenges_since_last_idle_round_(kIdleScavengeThreshold),
15832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      gcs_since_last_deopt_(0),
15994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#ifdef VERIFY_HEAP
16094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      no_weak_embedded_maps_verification_scope_depth_(0),
16194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#endif
162c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      promotion_queue_(this),
163ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      configured_(false),
164ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      chunks_queued_for_free_(NULL),
165ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      relocation_mutex_(NULL) {
166ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Allow build-time customization of the max semispace size. Building
167ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // V8 with snapshots and a non-default max semispace size is much
168ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // easier if you can define it as part of the build environment.
169ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#if defined(V8_MAX_SEMISPACE_SIZE)
170ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
171ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif
172ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
173ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org  intptr_t max_virtual = OS::MaxVirtualMemory();
174ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org
175ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org  if (max_virtual > 0) {
176ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org    if (code_range_size_ > 0) {
177ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org      // Reserve no more than 1/8 of the memory for the code range.
178ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org      code_range_size_ = Min(code_range_size_, max_virtual >> 3);
179ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org    }
180ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org  }
181ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org
182ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
18346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  native_contexts_list_ = NULL;
1841fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  array_buffers_list_ = Smi::FromInt(0);
185ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  allocation_sites_list_ = Smi::FromInt(0);
186ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  mark_compact_collector_.heap_ = this;
187ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  external_string_table_.heap_ = this;
188cb9affa86506f210b7d9b425012b1026b4fd0f2fyangguo@chromium.org  // Put a dummy entry in the remembered pages so we can find the list the
189cb9affa86506f210b7d9b425012b1026b4fd0f2fyangguo@chromium.org  // minidump even if there are no real unmapped pages.
190cb9affa86506f210b7d9b425012b1026b4fd0f2fyangguo@chromium.org  RememberUnmappedPage(NULL, false);
19128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
19228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  ClearObjectStats(true);
193ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
196f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.orgintptr_t Heap::Capacity() {
197f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return 0;
19843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1995a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return new_space_.Capacity() +
2009258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      old_pointer_space_->Capacity() +
2019258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      old_data_space_->Capacity() +
20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      code_space_->Capacity() +
203defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      map_space_->Capacity() +
20441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      cell_space_->Capacity() +
20541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      property_cell_space_->Capacity();
20643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
209f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.orgintptr_t Heap::CommittedMemory() {
210f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return 0;
2113811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
2123811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  return new_space_.CommittedMemory() +
2133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      old_pointer_space_->CommittedMemory() +
2143811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      old_data_space_->CommittedMemory() +
2153811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      code_space_->CommittedMemory() +
2163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      map_space_->CommittedMemory() +
2173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      cell_space_->CommittedMemory() +
21841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      property_cell_space_->CommittedMemory() +
2193811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      lo_space_->Size();
2203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
2213811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
22272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
22372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgsize_t Heap::CommittedPhysicalMemory() {
22472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  if (!HasBeenSetUp()) return 0;
22572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
22672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return new_space_.CommittedPhysicalMemory() +
22772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      old_pointer_space_->CommittedPhysicalMemory() +
22872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      old_data_space_->CommittedPhysicalMemory() +
22972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      code_space_->CommittedPhysicalMemory() +
23072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      map_space_->CommittedPhysicalMemory() +
23172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      cell_space_->CommittedPhysicalMemory() +
23241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      property_cell_space_->CommittedPhysicalMemory() +
23372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      lo_space_->CommittedPhysicalMemory();
23472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
23572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
23672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
23701fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.orgintptr_t Heap::CommittedMemoryExecutable() {
238f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return 0;
23901fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
240ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate()->memory_allocator()->SizeExecutable();
24101fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org}
24201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
2433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
244f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.orgintptr_t Heap::Available() {
245f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return 0;
24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2475a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return new_space_.Available() +
2489258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      old_pointer_space_->Available() +
2499258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      old_data_space_->Available() +
25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      code_space_->Available() +
251defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      map_space_->Available() +
25241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      cell_space_->Available() +
25341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      property_cell_space_->Available();
25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
257f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.combool Heap::HasBeenSetUp() {
2585a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return old_pointer_space_ != NULL &&
2599258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org         old_data_space_ != NULL &&
2609258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org         code_space_ != NULL &&
2619258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org         map_space_ != NULL &&
262defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org         cell_space_ != NULL &&
26341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org         property_cell_space_ != NULL &&
2649258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org         lo_space_ != NULL;
26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
268d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgint Heap::GcSafeSizeOfOldObject(HeapObject* object) {
269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (IntrusiveMarking::IsMarked(object)) {
270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return IntrusiveMarking::SizeOfMarkedObject(object);
271d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return object->SizeFromMap(object->map());
273d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org}
274d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
275d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
276994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgGarbageCollector Heap::SelectGarbageCollector(AllocationSpace space,
277994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                                              const char** reason) {
27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Is global GC requested?
279efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  if (space != NEW_SPACE) {
280ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->counters()->gc_compactor_caused_by_request()->Increment();
281994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    *reason = "GC in old space requested";
28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return MARK_COMPACTOR;
28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
285efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) {
286efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org    *reason = "GC in old space forced by flags";
287efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org    return MARK_COMPACTOR;
288efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  }
289efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Is enough data promoted to justify a global GC?
291a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (OldGenerationAllocationLimitReached()) {
292ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->counters()->gc_compactor_caused_by_promoted_data()->Increment();
293994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    *reason = "promotion limit reached";
29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return MARK_COMPACTOR;
29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Have allocation in OLD and LO failed?
29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (old_gen_exhausted_) {
299ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->counters()->
300ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        gc_compactor_caused_by_oldspace_exhaustion()->Increment();
301994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    *reason = "old generations exhausted";
30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return MARK_COMPACTOR;
30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Is there enough space left in OLD to guarantee that a scavenge can
30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // succeed?
30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
3089258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // Note that MemoryAllocator->MaxAvailable() undercounts the memory available
30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for object promotion. It counts only the bytes that the memory
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // allocator has not yet allocated from the OS and assigned to any space,
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // and does not count available bytes already in the old space or code
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // space.  Undercounting is safe---we may get an unrequested full GC when
31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // a scavenge would have succeeded.
314ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (isolate_->memory_allocator()->MaxAvailable() <= new_space_.Size()) {
315ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->counters()->
316ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        gc_compactor_caused_by_oldspace_exhaustion()->Increment();
317994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    *reason = "scavenge might not succeed";
31843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return MARK_COMPACTOR;
31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Default
322994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  *reason = NULL;
32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return SCAVENGER;
32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// TODO(1238405): Combine the infrastructure for --heap-stats and
32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// --log-gc to avoid the complicated preprocessor and flag testing.
32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ReportStatisticsBeforeGC() {
33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Heap::ReportHeapStatistics will also log NewSpace statistics when
331030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // compiled --log-gc is set.  The following logic is used to avoid
332030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // double logging.
333030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#ifdef DEBUG
3345a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  if (FLAG_heap_stats || FLAG_log_gc) new_space_.CollectStatistics();
33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_heap_stats) {
33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ReportHeapStatistics("Before GC");
33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (FLAG_log_gc) {
3385a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.ReportStatistics();
33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3405a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  if (FLAG_heap_stats || FLAG_log_gc) new_space_.ClearHistograms();
341030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#else
34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_log_gc) {
3435a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.CollectStatistics();
3445a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.ReportStatistics();
3455a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.ClearHistograms();
34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
347030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif  // DEBUG
34843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
34943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
351e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgvoid Heap::PrintShortHeapStatistics() {
352e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  if (!FLAG_trace_gc_verbose) return;
353657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  PrintPID("Memory allocator,   used: %6" V8_PTR_PREFIX "d KB"
354657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB\n",
355657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           isolate_->memory_allocator()->Size() / KB,
356657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           isolate_->memory_allocator()->Available() / KB);
357657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  PrintPID("New space,          used: %6" V8_PTR_PREFIX "d KB"
358657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB"
359657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", committed: %6" V8_PTR_PREFIX "d KB\n",
360657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           new_space_.Size() / KB,
361657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           new_space_.Available() / KB,
362657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           new_space_.CommittedMemory() / KB);
363657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  PrintPID("Old pointers,       used: %6" V8_PTR_PREFIX "d KB"
364657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB"
365657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", committed: %6" V8_PTR_PREFIX "d KB\n",
366657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_pointer_space_->SizeOfObjects() / KB,
367657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_pointer_space_->Available() / KB,
368657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_pointer_space_->CommittedMemory() / KB);
369657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  PrintPID("Old data space,     used: %6" V8_PTR_PREFIX "d KB"
370657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB"
371657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", committed: %6" V8_PTR_PREFIX "d KB\n",
372657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_data_space_->SizeOfObjects() / KB,
373657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_data_space_->Available() / KB,
374657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_data_space_->CommittedMemory() / KB);
375657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  PrintPID("Code space,         used: %6" V8_PTR_PREFIX "d KB"
376657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB"
377657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", committed: %6" V8_PTR_PREFIX "d KB\n",
378657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           code_space_->SizeOfObjects() / KB,
379657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           code_space_->Available() / KB,
380657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           code_space_->CommittedMemory() / KB);
381657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  PrintPID("Map space,          used: %6" V8_PTR_PREFIX "d KB"
382657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB"
383657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", committed: %6" V8_PTR_PREFIX "d KB\n",
384657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           map_space_->SizeOfObjects() / KB,
385657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           map_space_->Available() / KB,
386657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           map_space_->CommittedMemory() / KB);
387657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  PrintPID("Cell space,         used: %6" V8_PTR_PREFIX "d KB"
388657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB"
389657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", committed: %6" V8_PTR_PREFIX "d KB\n",
390657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           cell_space_->SizeOfObjects() / KB,
391657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           cell_space_->Available() / KB,
392657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           cell_space_->CommittedMemory() / KB);
39341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  PrintPID("PropertyCell space, used: %6" V8_PTR_PREFIX "d KB"
39441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB"
39541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org               ", committed: %6" V8_PTR_PREFIX "d KB\n",
39641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org           property_cell_space_->SizeOfObjects() / KB,
39741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org           property_cell_space_->Available() / KB,
39841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org           property_cell_space_->CommittedMemory() / KB);
399657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  PrintPID("Large object space, used: %6" V8_PTR_PREFIX "d KB"
400657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB"
401657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               ", committed: %6" V8_PTR_PREFIX "d KB\n",
402657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           lo_space_->SizeOfObjects() / KB,
403657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           lo_space_->Available() / KB,
404657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           lo_space_->CommittedMemory() / KB);
40533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  PrintPID("All spaces,         used: %6" V8_PTR_PREFIX "d KB"
40633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org               ", available: %6" V8_PTR_PREFIX "d KB"
40733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org               ", committed: %6" V8_PTR_PREFIX "d KB\n",
40833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org           this->SizeOfObjects() / KB,
40933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org           this->Available() / KB,
41033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org           this->CommittedMemory() / KB);
411f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org  PrintPID("External memory reported: %6" V8_PTR_PREFIX "d KB\n",
412f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org           amount_of_external_allocated_memory_ / KB);
413c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  PrintPID("Total time spent in GC  : %.1f ms\n", total_gc_time_ms_);
414e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org}
415e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
416e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// TODO(1238405): Combine the infrastructure for --heap-stats and
41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// --log-gc to avoid the complicated preprocessor and flag testing.
41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ReportStatisticsAfterGC() {
42043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Similar to the before GC, we use some complicated logic to ensure that
42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // NewSpace statistics are logged exactly once when --log-gc is turned on.
422030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#if defined(DEBUG)
42343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_heap_stats) {
4242abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    new_space_.CollectStatistics();
42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ReportHeapStatistics("After GC");
42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (FLAG_log_gc) {
4275a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.ReportStatistics();
42843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
429030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#else
4305a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  if (FLAG_log_gc) new_space_.ReportStatistics();
431030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif  // DEBUG
43243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::GarbageCollectionPrologue() {
43679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  {  AllowHeapAllocation for_the_first_part_of_prologue;
43779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    isolate_->transcendental_cache()->Clear();
43879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    ClearJSFunctionResultCaches();
43979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    gc_count_++;
44079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    unflattened_strings_length_ = 0;
44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    if (FLAG_flush_code && FLAG_flush_code_incrementally) {
44379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      mark_compact_collector()->EnableCodeFlushing(true);
44479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    }
445e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
446c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
44779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    if (FLAG_verify_heap) {
44879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      Verify();
44979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    }
450c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
45179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  }
452c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
453c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef DEBUG
45479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  ASSERT(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC);
45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_gc_verbose) Print();
45743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ReportStatisticsBeforeGC();
459030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif  // DEBUG
4600ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->GCPrologue();
46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
46343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
465f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.orgintptr_t Heap::SizeOfObjects() {
466f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  intptr_t total = 0;
4677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  AllSpaces spaces(this);
468b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
4694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    total += space->SizeOfObjects();
470911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  }
4719258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  return total;
47243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
47343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
47456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
47556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.orgvoid Heap::RepairFreeListsAfterBoot() {
4767c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  PagedSpaces spaces(this);
47756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  for (PagedSpace* space = spaces.next();
47856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org       space != NULL;
47956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org       space = spaces.next()) {
48056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    space->RepairFreeListsAfterBoot();
48156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  }
48256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org}
48356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
48456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::GarbageCollectionEpilogue() {
486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->GCEpilogue();
48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
488c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // In release mode, we only zap the from space under heap verification.
489c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  if (Heap::ShouldZapGarbage()) {
490c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    ZapFromSpace();
491c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  }
492c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
493c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
49443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_verify_heap) {
49543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Verify();
49643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
497c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
49843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowHeapAllocation for_the_rest_of_the_epilogue;
50079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org
501c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef DEBUG
502ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (FLAG_print_global_handles) isolate_->global_handles()->Print();
50343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_print_handles) PrintHandles();
50443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_gc_verbose) Print();
50543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_code_stats) ReportCodeStatistics("After GC");
50643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
50732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (FLAG_deopt_every_n_garbage_collections > 0) {
50832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (++gcs_since_last_deopt_ == FLAG_deopt_every_n_garbage_collections) {
50932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      Deoptimizer::DeoptimizeAll(isolate());
51032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      gcs_since_last_deopt_ = 0;
51132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    }
51232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
51343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
514ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->counters()->alive_after_last_gc()->Set(
515ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      static_cast<int>(SizeOfObjects()));
51643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  isolate_->counters()->string_table_capacity()->Set(
5184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      string_table()->Capacity());
519ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->counters()->number_of_symbols()->Set(
5204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      string_table()->NumberOfElements());
5217a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
522753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (CommittedMemory() > 0) {
523753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    isolate_->counters()->external_fragmentation_total()->AddSample(
524753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org        static_cast<int>(100 - (SizeOfObjects() * 100.0) / CommittedMemory()));
525471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
526471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_fraction_map_space()->AddSample(
527471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(
528471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            (map_space()->CommittedMemory() * 100.0) / CommittedMemory()));
529471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_fraction_cell_space()->AddSample(
530471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(
531471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            (cell_space()->CommittedMemory() * 100.0) / CommittedMemory()));
53241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    isolate_->counters()->heap_fraction_property_cell_space()->
53341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        AddSample(static_cast<int>(
53441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            (property_cell_space()->CommittedMemory() * 100.0) /
53541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            CommittedMemory()));
536471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
537471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_sample_total_committed()->AddSample(
538471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(CommittedMemory() / KB));
539471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_sample_total_used()->AddSample(
540471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(SizeOfObjects() / KB));
541471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_sample_map_space_committed()->AddSample(
542471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(map_space()->CommittedMemory() / KB));
543471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_sample_cell_space_committed()->AddSample(
544471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(cell_space()->CommittedMemory() / KB));
54541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    isolate_->counters()->
54641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        heap_sample_property_cell_space_committed()->
54741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            AddSample(static_cast<int>(
54841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                property_cell_space()->CommittedMemory() / KB));
549753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  }
550753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
551753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#define UPDATE_COUNTERS_FOR_SPACE(space)                                       \
552753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  isolate_->counters()->space##_bytes_available()->Set(                        \
553753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(space()->Available()));                                 \
554753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  isolate_->counters()->space##_bytes_committed()->Set(                        \
555753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(space()->CommittedMemory()));                           \
556753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  isolate_->counters()->space##_bytes_used()->Set(                             \
557753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(space()->SizeOfObjects()));
558753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#define UPDATE_FRAGMENTATION_FOR_SPACE(space)                                  \
559753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (space()->CommittedMemory() > 0) {                                        \
560753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    isolate_->counters()->external_fragmentation_##space()->AddSample(         \
561753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org        static_cast<int>(100 -                                                 \
562753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org            (space()->SizeOfObjects() * 100.0) / space()->CommittedMemory())); \
563753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  }
564753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#define UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(space)                     \
565753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_FOR_SPACE(space)                                             \
566753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_FRAGMENTATION_FOR_SPACE(space)
567753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
56828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  UPDATE_COUNTERS_FOR_SPACE(new_space)
569753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_pointer_space)
570753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_data_space)
571753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(code_space)
572753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(map_space)
573753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(cell_space)
57441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(property_cell_space)
575753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(lo_space)
57628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org#undef UPDATE_COUNTERS_FOR_SPACE
577753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#undef UPDATE_FRAGMENTATION_FOR_SPACE
578753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE
5797a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
580030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#if defined(DEBUG)
58143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ReportStatisticsAfterGC();
582030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif  // DEBUG
5837c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
584ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->debug()->AfterGarbageCollection();
5857c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org#endif  // ENABLE_DEBUGGER_SUPPORT
58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
58743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
589994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgvoid Heap::CollectAllGarbage(int flags, const char* gc_reason) {
5909258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // Since we are ignoring the return value, the exact choice of space does
5919258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // not matter, so long as we do not specify NEW_SPACE, which would not
5929258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // cause a full GC.
593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  mark_compact_collector_.SetFlags(flags);
594994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  CollectGarbage(OLD_POINTER_SPACE, gc_reason);
595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  mark_compact_collector_.SetFlags(kNoGCFlags);
5969258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
5979258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
5989258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
599994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgvoid Heap::CollectAllAvailableGarbage(const char* gc_reason) {
600f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Since we are ignoring the return value, the exact choice of space does
601f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // not matter, so long as we do not specify NEW_SPACE, which would not
602f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // cause a full GC.
603f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Major GC would invoke weak handle callbacks on weakly reachable
604f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // handles, but won't collect weakly reachable objects until next
605f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // major GC.  Therefore if we collect aggressively and weak handle callback
606f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // has been invoked, we rerun major GC to release objects which become
607f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // garbage.
608f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Note: as weak callbacks can execute arbitrary code, we cannot
609f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // hope that eventually there will be no weak callbacks invocations.
610f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Therefore stop recollecting after several attempts.
611994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  mark_compact_collector()->SetFlags(kMakeHeapIterableMask |
612994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                                     kReduceMemoryFootprintMask);
613c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  isolate_->compilation_cache()->Clear();
614f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  const int kMaxNumberOfAttempts = 7;
615bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  const int kMinNumberOfAttempts = 2;
616f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) {
617bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    if (!CollectGarbage(OLD_POINTER_SPACE, MARK_COMPACTOR, gc_reason, NULL) &&
618bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        attempt + 1 >= kMinNumberOfAttempts) {
619f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org      break;
620f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org    }
621f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  }
622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  mark_compact_collector()->SetFlags(kNoGCFlags);
623c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  new_space_.Shrink();
624bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org  UncommitFromSpace();
625c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  incremental_marking()->UncommitMarkingDeque();
626f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org}
627f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
628f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
629994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgbool Heap::CollectGarbage(AllocationSpace space,
630994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                          GarbageCollector collector,
631994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                          const char* gc_reason,
632994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                          const char* collector_reason) {
63343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The VM is in the GC state until exiting this function.
634ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  VMState<GC> state(isolate_);
63543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
63643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
63743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Reset the allocation timeout to the GC interval, but make sure to
63843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // allow at least a few allocations after a collection. The reason
63943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for this is that we have a lot of allocation sequences and we
64043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // assume that a garbage collection will allow the subsequent
64143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // allocation attempts to go through.
64243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  allocation_timeout_ = Max(6, FLAG_gc_interval);
64343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
64443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
645c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (collector == SCAVENGER && !incremental_marking()->IsStopped()) {
646c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (FLAG_trace_incremental_marking) {
647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      PrintF("[IncrementalMarking] Scavenge during marking.\n");
648c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
650c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
651c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (collector == MARK_COMPACTOR &&
65283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      !mark_compact_collector()->abort_incremental_marking() &&
653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !incremental_marking()->IsStopped() &&
654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !incremental_marking()->should_hurry() &&
655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      FLAG_incremental_marking_steps) {
6567d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    // Make progress in incremental marking.
6577d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    const intptr_t kStepSizeWhenDelayedByScavenge = 1 * MB;
6587d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    incremental_marking()->Step(kStepSizeWhenDelayedByScavenge,
6597d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org                                IncrementalMarking::NO_GC_VIA_STACK_GUARD);
6607d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    if (!incremental_marking()->IsComplete()) {
6617d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org      if (FLAG_trace_incremental_marking) {
6627d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org        PrintF("[IncrementalMarking] Delaying MarkSweep.\n");
6637d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org      }
6647d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org      collector = SCAVENGER;
6657d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org      collector_reason = "incremental marking delaying mark-sweep";
666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
669f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  bool next_gc_likely_to_collect_more = false;
670f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
671994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  { GCTracer tracer(this, gc_reason, collector_reason);
67279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    ASSERT(AllowHeapAllocation::IsAllowed());
67379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_allocation_during_gc;
67443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    GarbageCollectionPrologue();
6757276f14ca716596e0a0d17539516370c1f453847kasper.lund    // The GC count was incremented in the prologue.  Tell the tracer about
6767276f14ca716596e0a0d17539516370c1f453847kasper.lund    // it.
6777276f14ca716596e0a0d17539516370c1f453847kasper.lund    tracer.set_gc_count(gc_count_);
67843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6797276f14ca716596e0a0d17539516370c1f453847kasper.lund    // Tell the tracer which collector we've selected.
68043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    tracer.set_collector(collector);
68143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6828e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    {
6838e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      HistogramTimerScope histogram_timer_scope(
6848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          (collector == SCAVENGER) ? isolate_->counters()->gc_scavenger()
6858e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                   : isolate_->counters()->gc_compactor());
6868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      next_gc_likely_to_collect_more =
6878e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          PerformGarbageCollection(collector, &tracer);
6888e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
68943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    GarbageCollectionEpilogue();
69143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
69243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Start incremental marking for the next cycle. The heap snapshot
69483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // generator needs incremental marking to stay off after it aborted.
69583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  if (!mark_compact_collector()->abort_incremental_marking() &&
69683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      incremental_marking()->IsStopped() &&
69783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      incremental_marking()->WorthActivating() &&
69883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      NextGCIsLikelyToBeFull()) {
69983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    incremental_marking()->Start();
700c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
701c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
702f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  return next_gc_likely_to_collect_more;
70343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
70443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
706594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgint Heap::NotifyContextDisposed() {
707594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (FLAG_parallel_recompilation) {
708594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Flush the queued recompilation tasks.
709594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    isolate()->optimizing_compiler_thread()->Flush();
710594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
711594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  flush_monomorphic_ics_ = true;
712594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return ++contexts_disposed_;
713594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
714594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
715594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
7167276f14ca716596e0a0d17539516370c1f453847kasper.lundvoid Heap::PerformScavenge() {
717994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  GCTracer tracer(this, NULL, NULL);
718c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (incremental_marking()->IsStopped()) {
719c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    PerformGarbageCollection(SCAVENGER, &tracer);
720c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
721c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    PerformGarbageCollection(MARK_COMPACTOR, &tracer);
722c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
7237276f14ca716596e0a0d17539516370c1f453847kasper.lund}
7247276f14ca716596e0a0d17539516370c1f453847kasper.lund
7257276f14ca716596e0a0d17539516370c1f453847kasper.lund
72659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgvoid Heap::MoveElements(FixedArray* array,
72759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                        int dst_index,
72859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                        int src_index,
72959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                        int len) {
73059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (len == 0) return;
73159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
73259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  ASSERT(array->map() != HEAP->fixed_cow_array_map());
73359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  Object** dst_objects = array->data_start() + dst_index;
734e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemMove(dst_objects,
735e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org              array->data_start() + src_index,
736e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org              len * kPointerSize);
73759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (!InNewSpace(array)) {
73859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    for (int i = 0; i < len; i++) {
73959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      // TODO(hpayer): check store buffer for entries
74059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      if (InNewSpace(dst_objects[i])) {
74159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        RecordWrite(array->address(), array->OffsetOfElementAt(dst_index + i));
74259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      }
74359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    }
74459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
74559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  incremental_marking()->RecordWrites(array);
74659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org}
74759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
74859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
749c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
7504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org// Helper class for verifying the string table.
7514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgclass StringTableVerifier : public ObjectVisitor {
752416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org public:
753416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org  void VisitPointers(Object** start, Object** end) {
754416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org    // Visit all HeapObject pointers in [start, end).
755416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org    for (Object** p = start; p < end; p++) {
756416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org      if ((*p)->IsHeapObject()) {
7574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        // Check that the string is actually internalized.
7584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        CHECK((*p)->IsTheHole() || (*p)->IsUndefined() ||
7594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              (*p)->IsInternalizedString());
760d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org      }
761d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org    }
762416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org  }
763416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org};
764d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
765416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org
7664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgstatic void VerifyStringTable() {
7674a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  StringTableVerifier verifier;
7684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  HEAP->string_table()->IterateElements(&verifier);
769d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org}
770c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif  // VERIFY_HEAP
771d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
772d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
773bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comstatic bool AbortIncrementalMarkingAndCollectGarbage(
774bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    Heap* heap,
775bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    AllocationSpace space,
776bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    const char* gc_reason = NULL) {
777bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  heap->mark_compact_collector()->SetFlags(Heap::kAbortIncrementalMarkingMask);
778bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  bool result = heap->CollectGarbage(space, gc_reason);
779bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  heap->mark_compact_collector()->SetFlags(Heap::kNoGCFlags);
780bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return result;
781bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
782bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
783bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
7840c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid Heap::ReserveSpace(
78556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    int *sizes,
78656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Address *locations_out) {
7870c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  bool gc_performed = true;
78805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  int counter = 0;
78905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  static const int kThreshold = 20;
79005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  while (gc_performed && counter++ < kThreshold) {
7910c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    gc_performed = false;
79256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(NEW_SPACE == FIRST_PAGED_SPACE - 1);
79356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    for (int space = NEW_SPACE; space <= LAST_PAGED_SPACE; space++) {
79456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      if (sizes[space] != 0) {
79556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        MaybeObject* allocation;
79656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        if (space == NEW_SPACE) {
79756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          allocation = new_space()->AllocateRaw(sizes[space]);
79856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        } else {
79956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          allocation = paged_space(space)->AllocateRaw(sizes[space]);
80056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        }
80156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        FreeListNode* node;
80256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        if (!allocation->To<FreeListNode>(&node)) {
80356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          if (space == NEW_SPACE) {
80456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org            Heap::CollectGarbage(NEW_SPACE,
80556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org                                 "failed to reserve space in the new space");
80656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          } else {
80756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org            AbortIncrementalMarkingAndCollectGarbage(
80856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org                this,
80956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org                static_cast<AllocationSpace>(space),
81056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org                "failed to reserve space in paged space");
81156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          }
81256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          gc_performed = true;
81356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          break;
81456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        } else {
81556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          // Mark with a free list node, in case we have a GC before
81656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          // deserializing.
81756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          node->set_size(this, sizes[space]);
81856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          locations_out[space] = node->address();
81956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        }
82056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      }
8210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
8220c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
82305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
82405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (gc_performed) {
82505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    // Failed to reserve the space after several attempts.
82605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    V8::FatalProcessOutOfMemory("Heap::ReserveSpace");
82705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
8280c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
8290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
8300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
831add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.orgvoid Heap::EnsureFromSpaceIsCommitted() {
832add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  if (new_space_.CommitFromSpaceIfNeeded()) return;
833add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org
834add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  // Committing memory to from space failed.
835add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  // Memory is exhausted and we will die.
836add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  V8::FatalProcessOutOfMemory("Committing semi space failed.");
837add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org}
838add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org
839add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org
840e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgvoid Heap::ClearJSFunctionResultCaches() {
841ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (isolate_->bootstrapper()->IsActive()) return;
842ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
84346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Object* context = native_contexts_list_;
844e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  while (!context->IsUndefined()) {
8457ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    // Get the caches for this context. GC can happen when the context
8467ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    // is not fully initialized, so the caches can be undefined.
8477ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    Object* caches_or_undefined =
8487ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        Context::cast(context)->get(Context::JSFUNCTION_RESULT_CACHES_INDEX);
8497ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    if (!caches_or_undefined->IsUndefined()) {
8507ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      FixedArray* caches = FixedArray::cast(caches_or_undefined);
8517ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      // Clear the caches:
8527ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      int length = caches->length();
8537ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      for (int i = 0; i < length; i++) {
8547ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        JSFunctionResultCache::cast(caches->get(i))->Clear();
8557ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      }
856ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org    }
857e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Get the next context:
858e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
859ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  }
860ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org}
861ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
862ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
86365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgvoid Heap::ClearNormalizedMapCaches() {
864c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (isolate_->bootstrapper()->IsActive() &&
865c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !incremental_marking()->IsMarking()) {
866c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return;
867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
8684a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
86946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Object* context = native_contexts_list_;
8704a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  while (!context->IsUndefined()) {
8717ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    // GC can happen when the context is not fully initialized,
8727ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    // so the cache can be undefined.
8737ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    Object* cache =
8747ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX);
8757ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    if (!cache->IsUndefined()) {
8767ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      NormalizedMapCache::cast(cache)->Clear();
8777ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    }
8784a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
8794a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  }
88065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
88165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
88265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
88340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.orgvoid Heap::UpdateSurvivalRateTrend(int start_new_space_size) {
88440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  double survival_rate =
88540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org      (static_cast<double>(young_survivors_after_last_gc_) * 100) /
88640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org      start_new_space_size;
88740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
888659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (survival_rate > kYoungSurvivalRateHighThreshold) {
88940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org    high_survival_rate_period_length_++;
89040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  } else {
89140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org    high_survival_rate_period_length_ = 0;
89240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  }
89340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
894659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (survival_rate < kYoungSurvivalRateLowThreshold) {
895659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    low_survival_rate_period_length_++;
896659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  } else {
897659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    low_survival_rate_period_length_ = 0;
898659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
899659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
90040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  double survival_rate_diff = survival_rate_ - survival_rate;
90140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
90240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) {
90340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org    set_survival_rate_trend(DECREASING);
90440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  } else if (survival_rate_diff < -kYoungSurvivalRateAllowedDeviation) {
90540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org    set_survival_rate_trend(INCREASING);
90640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  } else {
90740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org    set_survival_rate_trend(STABLE);
90840b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  }
90940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
91040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  survival_rate_ = survival_rate;
91140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org}
91230ce411529579186181838984710b0b0980857aaricow@chromium.org
913f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.orgbool Heap::PerformGarbageCollection(GarbageCollector collector,
914303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                    GCTracer* tracer) {
915f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  bool next_gc_likely_to_collect_more = false;
916f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
9174a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  if (collector != SCAVENGER) {
918ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    PROFILE(isolate_, CodeMovingGCEvent());
9194a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  }
9204a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
921c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
922394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
9234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    VerifyStringTable();
924394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
925c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
926c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
9275d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  GCType gc_type =
9285d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge;
9295d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
93046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  {
93146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
932ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    VMState<EXTERNAL> state(isolate_);
933fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    HandleScope handle_scope(isolate_);
934ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags);
9355d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
9365d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
937add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  EnsureFromSpaceIsCommitted();
938ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
939f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  int start_new_space_size = Heap::new_space()->SizeAsInt();
94040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (IsHighSurvivalRate()) {
942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // We speed up the incremental marker if it is running so that it
943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // does not fall behind the rate of promotion, which would cause a
944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // constantly growing old space.
945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    incremental_marking()->NotifyOfHighPromotionRate();
946c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
947c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
94843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (collector == MARK_COMPACTOR) {
949b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    // Perform mark-sweep with optional compaction.
9507276f14ca716596e0a0d17539516370c1f453847kasper.lund    MarkCompact(tracer);
951ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    sweep_generation_++;
95240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
95340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org    UpdateSurvivalRateTrend(start_new_space_size);
95440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
955212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSizeOfObjects();
956303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
957a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    old_generation_allocation_limit_ =
958a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        OldGenerationAllocationLimit(size_of_old_gen_at_last_old_space_gc_);
959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
960303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    old_gen_exhausted_ = false;
961b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  } else {
9629dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    tracer_ = tracer;
963b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    Scavenge();
9649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    tracer_ = NULL;
96540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
96640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org    UpdateSurvivalRateTrend(start_new_space_size);
96743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
968439e85a92a8f3544428743c458d4941ad6deb1c2ager@chromium.org
969659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (!new_space_high_promotion_mode_active_ &&
970659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      new_space_.Capacity() == new_space_.MaximumCapacity() &&
971659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      IsStableOrIncreasingSurvivalTrend() &&
972659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      IsHighSurvivalRate()) {
973659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // Stable high survival rates even though young generation is at
974659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // maximum capacity indicates that most objects will be promoted.
975659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // To decrease scavenger pauses and final mark-sweep pauses, we
976659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // have to limit maximal capacity of the young generation.
977a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    SetNewSpaceHighPromotionModeActive(true);
978659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (FLAG_trace_gc) {
979657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org      PrintPID("Limited new space size due to high promotion rate: %d MB\n",
980657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               new_space_.InitialCapacity() / MB);
981659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
982e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Support for global pre-tenuring uses the high promotion mode as a
983e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // heuristic indicator of whether to pretenure or not, we trigger
984e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // deoptimization here to take advantage of pre-tenuring as soon as
985e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // possible.
986a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (FLAG_pretenuring) {
987e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      isolate_->stack_guard()->FullDeopt();
988e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
989659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  } else if (new_space_high_promotion_mode_active_ &&
990659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      IsStableOrDecreasingSurvivalTrend() &&
991659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      IsLowSurvivalRate()) {
992659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // Decreasing low survival rates might indicate that the above high
993659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // promotion mode is over and we should allow the young generation
994659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // to grow again.
995a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    SetNewSpaceHighPromotionModeActive(false);
996659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (FLAG_trace_gc) {
997657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org      PrintPID("Unlimited new space size due to low promotion rate: %d MB\n",
998657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org               new_space_.MaximumCapacity() / MB);
999659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
1000e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Trigger deoptimization here to turn off pre-tenuring as soon as
1001e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // possible.
1002a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (FLAG_pretenuring) {
1003e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      isolate_->stack_guard()->FullDeopt();
1004e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
1005659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
1006659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
10071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (new_space_high_promotion_mode_active_ &&
10081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      new_space_.Capacity() > new_space_.InitialCapacity()) {
10091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    new_space_.Shrink();
10101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
10111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
1012ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->counters()->objs_since_last_young()->Set(0);
101343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
101483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Callbacks that fire after this point might trigger nested GCs and
101583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // restart incremental marking, the assertion can't be moved down.
101683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped());
101783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
1018d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  gc_post_processing_depth_++;
101979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  { AllowHeapAllocation allow_allocation;
1020303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
1021f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org    next_gc_likely_to_collect_more =
1022cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org        isolate_->global_handles()->PostGarbageCollectionProcessing(
1023cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org            collector, tracer);
1024303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
1025d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  gc_post_processing_depth_--;
1026303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
1027594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  isolate_->eternal_handles()->PostGarbageCollectionProcessing(this);
1028594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
10293811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Update relocatables.
10303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  Relocatable::PostGarbageCollectionProcessing();
103143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10327276f14ca716596e0a0d17539516370c1f453847kasper.lund  if (collector == MARK_COMPACTOR) {
10337276f14ca716596e0a0d17539516370c1f453847kasper.lund    // Register the amount of external allocated memory.
10347276f14ca716596e0a0d17539516370c1f453847kasper.lund    amount_of_external_allocated_memory_at_last_global_gc_ =
10357276f14ca716596e0a0d17539516370c1f453847kasper.lund        amount_of_external_allocated_memory_;
10367276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
10377276f14ca716596e0a0d17539516370c1f453847kasper.lund
103846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  {
103946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
1040ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    VMState<EXTERNAL> state(isolate_);
1041fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    HandleScope handle_scope(isolate_);
1042003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    CallGCEpilogueCallbacks(gc_type);
104343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1044c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
1045c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
1046394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
10474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    VerifyStringTable();
1048394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
1049c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
1050f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1051f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  return next_gc_likely_to_collect_more;
105243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
105343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1055ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) {
1056003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (gc_type == kGCTypeMarkSweepCompact && global_gc_prologue_callback_) {
1057003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    global_gc_prologue_callback_();
1058003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
1059003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
1060003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    if (gc_type & gc_prologue_callbacks_[i].gc_type) {
1061ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      gc_prologue_callbacks_[i].callback(gc_type, flags);
1062003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
1063003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
1064003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
1065003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1066003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1067003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgvoid Heap::CallGCEpilogueCallbacks(GCType gc_type) {
1068003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
1069003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    if (gc_type & gc_epilogue_callbacks_[i].gc_type) {
1070003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      gc_epilogue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags);
1071003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
1072003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
1073003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (gc_type == kGCTypeMarkSweepCompact && global_gc_epilogue_callback_) {
1074003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    global_gc_epilogue_callback_();
1075003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
1076003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
1077003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1078003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
10797276f14ca716596e0a0d17539516370c1f453847kasper.lundvoid Heap::MarkCompact(GCTracer* tracer) {
108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  gc_state_ = MARK_COMPACT;
1081ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, ResourceEvent("markcompact", "begin"));
108243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1083ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  mark_compact_collector_.Prepare(tracer);
1084061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
1085c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ms_count_++;
1086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  tracer->set_full_gc_count(ms_count_);
10872356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
1088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkCompactPrologue();
108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1090ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  mark_compact_collector_.CollectGarbage();
109143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1092ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, ResourceEvent("markcompact", "end"));
109343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
109443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  gc_state_ = NOT_IN_GC;
109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1096ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->counters()->objs_since_last_full()->Set(0);
10978b2bb2665b37457fd2bdccbce0356051c83a73fckasperl@chromium.org
10988b2bb2665b37457fd2bdccbce0356051c83a73fckasperl@chromium.org  contexts_disposed_ = 0;
10992efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
1100c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  flush_monomorphic_ics_ = false;
110143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
110243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
110343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::MarkCompactPrologue() {
1105061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  // At any old GC clear the keyed lookup cache to enable collection of unused
1106061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  // maps.
1107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->keyed_lookup_cache()->Clear();
1108ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->context_slot_cache()->Clear();
1109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->descriptor_lookup_cache()->Clear();
111078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  RegExpResultsCache::Clear(string_split_cache());
111178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  RegExpResultsCache::Clear(regexp_multiple_cache());
1112061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
1113ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->compilation_cache()->MarkCompactPrologue();
1114061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
1115720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  CompletelyClearInstanceofCache();
1116720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
1117fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  FlushNumberStringCache();
1118e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  if (FLAG_cleanup_code_caches_at_gc) {
1119e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    polymorphic_code_cache()->set_cache(undefined_value());
1120e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
112165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
112265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ClearNormalizedMapCaches();
112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
112443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
112643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper class for copying HeapObjects
11275a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgclass ScavengeVisitor: public ObjectVisitor {
112843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
1129ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit ScavengeVisitor(Heap* heap) : heap_(heap) {}
113043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11315a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  void VisitPointer(Object** p) { ScavengePointer(p); }
113243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void VisitPointers(Object** start, Object** end) {
113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Copy all HeapObject pointers in [start, end)
11355a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    for (Object** p = start; p < end; p++) ScavengePointer(p);
113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
11395a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  void ScavengePointer(Object** p) {
11405a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    Object* object = *p;
1141ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (!heap_->InNewSpace(object)) return;
11425a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p),
11435a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                         reinterpret_cast<HeapObject*>(object));
114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
114543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1146ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap_;
1147b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org};
1148b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1149b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1150c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
11519258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// Visitor class to verify pointers in code or data space do not point into
115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// new space.
11539258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgclass VerifyNonPointerSpacePointersVisitor: public ObjectVisitor {
115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void VisitPointers(Object** start, Object**end) {
115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (Object** current = start; current < end; current++) {
115743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if ((*current)->IsHeapObject()) {
1158c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org        CHECK(!HEAP->InNewSpace(HeapObject::cast(*current)));
115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
116043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
116143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
116243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
11639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
1164b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1165b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgstatic void VerifyNonPointerSpacePointers() {
1166b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // Verify that there are no pointers to new space in spaces where we
1167b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // do not expect them.
1168b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  VerifyNonPointerSpacePointersVisitor v;
1169ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HeapObjectIterator code_it(HEAP->code_space());
1170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (HeapObject* object = code_it.Next();
1171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       object != NULL; object = code_it.Next())
11722bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com    object->Iterate(&v);
1173b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The old data space was normally swept conservatively so that the iterator
1175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // doesn't work, so we normally skip the next bit.
1176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!HEAP->old_data_space()->was_swept_conservatively()) {
1177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    HeapObjectIterator data_it(HEAP->old_data_space());
1178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    for (HeapObject* object = data_it.Next();
1179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         object != NULL; object = data_it.Next())
1180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      object->Iterate(&v);
1181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1182b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org}
1183c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif  // VERIFY_HEAP
1184b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1185defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
1186b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.orgvoid Heap::CheckNewSpaceExpansionCriteria() {
1187b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  if (new_space_.Capacity() < new_space_.MaximumCapacity() &&
11881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      survived_since_last_expansion_ > new_space_.Capacity() &&
11891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      !new_space_high_promotion_mode_active_) {
11901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Grow the size of new space if there is room to grow, enough data
11911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // has survived scavenge since the last expansion and we are not in
11921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // high promotion mode.
1193b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    new_space_.Grow();
1194b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    survived_since_last_expansion_ = 0;
1195b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
1196b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
1197b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1198b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1199c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgstatic bool IsUnscavengedHeapObject(Heap* heap, Object** p) {
1200c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  return heap->InNewSpace(*p) &&
1201c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      !HeapObject::cast(*p)->map_word().IsForwardingAddress();
1202c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org}
1203c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1204c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::ScavengeStoreBufferCallback(
1206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Heap* heap,
1207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MemoryChunk* page,
1208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    StoreBufferEvent event) {
1209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap->store_buffer_rebuilder_.Callback(page, event);
1210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
1211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBufferRebuilder::Callback(MemoryChunk* page, StoreBufferEvent event) {
1214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (event == kStoreBufferStartScanningPagesEvent) {
1215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    start_of_current_page_ = NULL;
1216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    current_page_ = NULL;
1217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (event == kStoreBufferScanningPageEvent) {
1218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (current_page_ != NULL) {
1219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // If this page already overflowed the store buffer during this iteration.
1220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (current_page_->scan_on_scavenge()) {
1221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Then we should wipe out the entries that have been added for it.
1222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        store_buffer_->SetTop(start_of_current_page_);
1223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else if (store_buffer_->Top() - start_of_current_page_ >=
1224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 (store_buffer_->Limit() - store_buffer_->Top()) >> 2) {
1225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Did we find too many pointers in the previous page?  The heuristic is
1226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // that no page can take more then 1/5 the remaining slots in the store
1227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // buffer.
1228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        current_page_->set_scan_on_scavenge(true);
1229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        store_buffer_->SetTop(start_of_current_page_);
1230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else {
1231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // In this case the page we scanned took a reasonable number of slots in
1232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // the store buffer.  It has now been rehabilitated and is no longer
1233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // marked scan_on_scavenge.
1234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ASSERT(!current_page_->scan_on_scavenge());
1235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
1236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
1237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    start_of_current_page_ = store_buffer_->Top();
1238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    current_page_ = page;
1239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (event == kStoreBufferFullEvent) {
1240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The current page overflowed the store buffer again.  Wipe out its entries
1241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // in the store buffer and mark it scan-on-scavenge again.  This may happen
1242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // several times while scanning.
1243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (current_page_ == NULL) {
1244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Store Buffer overflowed while scanning promoted objects.  These are not
1245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // in any particular page, though they are likely to be clustered by the
1246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // allocation routines.
124741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      store_buffer_->EnsureSpace(StoreBuffer::kStoreBufferSize / 2);
1248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
1249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Store Buffer overflowed while scanning a particular old space page for
1250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // pointers to new space.
1251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(current_page_ == page);
1252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(page != NULL);
1253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current_page_->set_scan_on_scavenge(true);
1254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(start_of_current_page_ != store_buffer_->Top());
1255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      store_buffer_->SetTop(start_of_current_page_);
1256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
1257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
1258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    UNREACHABLE();
1259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
1261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1263c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgvoid PromotionQueue::Initialize() {
1264c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // Assumes that a NewSpacePage exactly fits a number of promotion queue
1265c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // entries (where each is a pair of intptr_t). This allows us to simplify
1266c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // the test fpr when to switch pages.
1267c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  ASSERT((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize)
1268c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org         == 0);
1269c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  limit_ = reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceStart());
1270c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  front_ = rear_ =
1271c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceEnd());
1272c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  emergency_stack_ = NULL;
1273c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  guard_ = false;
1274c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org}
1275c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1276c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1277c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgvoid PromotionQueue::RelocateQueueHead() {
1278c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  ASSERT(emergency_stack_ == NULL);
1279c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1280c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Page* p = Page::FromAllocationTop(reinterpret_cast<Address>(rear_));
1281c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  intptr_t* head_start = rear_;
1282c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  intptr_t* head_end =
1283ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      Min(front_, reinterpret_cast<intptr_t*>(p->area_end()));
1284c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1285c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int entries_count =
1286c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      static_cast<int>(head_end - head_start) / kEntrySizeInWords;
1287c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1288c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  emergency_stack_ = new List<Entry>(2 * entries_count);
1289c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1290c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  while (head_start != head_end) {
1291c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    int size = static_cast<int>(*(head_start++));
1292c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    HeapObject* obj = reinterpret_cast<HeapObject*>(*(head_start++));
1293c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    emergency_stack_->Add(Entry(obj, size));
1294c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  }
1295c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  rear_ = head_end;
1296c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org}
1297c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1298c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1299ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comclass ScavengeWeakObjectRetainer : public WeakObjectRetainer {
1300ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com public:
1301ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  explicit ScavengeWeakObjectRetainer(Heap* heap) : heap_(heap) { }
1302ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1303ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  virtual Object* RetainAs(Object* object) {
1304ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (!heap_->InFromSpace(object)) {
1305ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      return object;
1306ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
1307ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1308ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    MapWord map_word = HeapObject::cast(object)->map_word();
1309ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (map_word.IsForwardingAddress()) {
1310ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      return map_word.ToForwardingAddress();
1311ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
1312ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    return NULL;
1313ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
1314ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1315ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com private:
1316ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  Heap* heap_;
1317ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com};
1318ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1319ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1320b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgvoid Heap::Scavenge() {
1321ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  RelocationLock relocation_lock(this);
1322ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1323c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
1324394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) VerifyNonPointerSpacePointers();
132543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
132643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  gc_state_ = SCAVENGE;
132843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Implements Cheney's copying algorithm
1330ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, ResourceEvent("scavenge", "begin"));
133143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13325aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Clear descriptor cache.
1333ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->descriptor_lookup_cache()->Clear();
13345aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
1335eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Used for updating survived_since_last_expansion_ at function end.
1336659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  intptr_t survived_watermark = PromotedSpaceSizeOfObjects();
1337eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1338b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  CheckNewSpaceExpansionCriteria();
133943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SelectScavengingVisitorsTable();
1341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  incremental_marking()->PrepareForScavenge();
1343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1344e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  paged_space(OLD_DATA_SPACE)->EnsureSweeperProgress(new_space_.Size());
1345e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  paged_space(OLD_POINTER_SPACE)->EnsureSweeperProgress(new_space_.Size());
1346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
134743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Flip the semispaces.  After flipping, to space is empty, from space has
134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // live objects.
13495a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  new_space_.Flip();
13505a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  new_space_.ResetAllocationInfo();
135143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1352b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // We need to sweep newly copied objects which can be either in the
1353b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // to space or promoted to the old generation.  For to-space
1354b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // objects, we treat the bottom of the to space as a queue.  Newly
1355b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // copied and unswept objects lie between a 'front' mark and the
1356b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // allocation pointer.
1357b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  //
1358b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // Promoted objects can go into various old-generation spaces, and
1359b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // can be allocated internally in the spaces (from the free list).
1360b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // We treat the top of the to space as a queue of addresses of
1361b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // promoted objects.  The addresses of newly promoted and unswept
1362b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // objects lie between a 'front' mark and a 'rear' mark that is
1363b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // updated as a side effect of promoting an object.
136443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
1365b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // There is guaranteed to be enough room at the top of the to space
1366b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // for the addresses of promoted objects: every object promoted
1367b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // frees up its size in bytes from the top of the new space, and
1368b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // objects are at least one pointer in size.
1369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address new_space_front = new_space_.ToSpaceStart();
1370c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  promotion_queue_.Initialize();
1371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG
1373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->Clean();
1374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1376ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ScavengeVisitor scavenge_visitor(this);
137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Copy roots.
137813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE);
1379b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Copy objects reachable from the old generation.
1381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
1382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    StoreBufferRebuildScope scope(this,
1383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  store_buffer(),
1384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  &ScavengeStoreBufferCallback);
1385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    store_buffer()->IteratePointersToNewSpace(&ScavengeObject);
1386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1387defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
138841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Copy objects reachable from simple cells by scavenging cell values
138941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // directly.
1390defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  HeapObjectIterator cell_iterator(cell_space_);
1391000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  for (HeapObject* heap_object = cell_iterator.Next();
1392000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org       heap_object != NULL;
1393000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org       heap_object = cell_iterator.Next()) {
139441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (heap_object->IsCell()) {
139541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Cell* cell = Cell::cast(heap_object);
139641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Address value_address = cell->ValueAddress();
139741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
139841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
139941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
140041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
140141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Copy objects reachable from global property cells by scavenging global
140241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // property cell values directly.
140341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  HeapObjectIterator js_global_property_cell_iterator(property_cell_space_);
140441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  for (HeapObject* heap_object = js_global_property_cell_iterator.Next();
140541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org       heap_object != NULL;
140641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org       heap_object = js_global_property_cell_iterator.Next()) {
1407b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (heap_object->IsPropertyCell()) {
1408b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      PropertyCell* cell = PropertyCell::cast(heap_object);
1409000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org      Address value_address = cell->ValueAddress();
1410defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
141141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Address type_address = cell->TypeAddress();
141241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(type_address));
1413defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    }
1414defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  }
141543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1416e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Copy objects reachable from the code flushing candidates list.
1417e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  MarkCompactCollector* collector = mark_compact_collector();
1418e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (collector->is_code_flushing_enabled()) {
1419e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor);
1420e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
1421e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
142246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Scavenge object reachable from the native contexts list directly.
142346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  scavenge_visitor.VisitPointer(BitCast<Object**>(&native_contexts_list_));
14244a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
142513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1426e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
142749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  while (isolate()->global_handles()->IterateObjectGroups(
142849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      &scavenge_visitor, &IsUnscavengedHeapObject)) {
1429e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1430e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
1431e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  isolate()->global_handles()->RemoveObjectGroups();
1432003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  isolate()->global_handles()->RemoveImplicitRefGroups();
1433e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1434e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
1435c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      &IsUnscavengedHeapObject);
1436e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
1437e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      &scavenge_visitor);
1438c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1439c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1440b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  UpdateNewSpaceReferencesInExternalStringTable(
1441b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org      &UpdateNewSpaceReferenceInExternalStringTableEntry);
1442b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1443c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  promotion_queue_.Destroy();
1444c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
144578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  if (!FLAG_watch_ic_patching) {
144678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
144778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
1448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  incremental_marking()->UpdateMarkingDequeAfterScavenge();
14490ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
1450ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  ScavengeWeakObjectRetainer weak_object_retainer(this);
1451ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  ProcessWeakReferences(&weak_object_retainer);
1452ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
145313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  ASSERT(new_space_front == new_space_.top());
145413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
145513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Set age mark.
145613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  new_space_.set_age_mark(new_space_.top());
145713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  new_space_.LowerInlineAllocationLimit(
1459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      new_space_.inline_allocation_limit_step());
1460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
146113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Update how much has survived scavenge.
1462f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  IncrementYoungSurvivorsCounter(static_cast<int>(
1463659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size()));
146413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1465ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, ResourceEvent("scavenge", "end"));
146613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
146713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  gc_state_ = NOT_IN_GC;
1468ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
1469ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  scavenges_since_last_idle_round_++;
147013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
147113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
147213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1473ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgString* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
1474ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                                Object** p) {
1475b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  MapWord first_word = HeapObject::cast(*p)->map_word();
1476b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1477b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  if (!first_word.IsForwardingAddress()) {
1478b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    // Unreachable external string can be finalized.
1479ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    heap->FinalizeExternalString(String::cast(*p));
1480b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    return NULL;
1481b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
1482b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1483b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  // String is still reachable.
1484b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  return String::cast(first_word.ToForwardingAddress());
1485b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
1486b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1487b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1488b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.orgvoid Heap::UpdateNewSpaceReferencesInExternalStringTable(
1489b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    ExternalStringTableUpdaterCallback updater_func) {
1490c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
1491394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
1492394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    external_string_table_.Verify();
1493394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
1494c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
149513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1496ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (external_string_table_.new_space_strings_.is_empty()) return;
149713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
14982ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  Object** start = &external_string_table_.new_space_strings_[0];
14992ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  Object** end = start + external_string_table_.new_space_strings_.length();
15002ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  Object** last = start;
150113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
15022ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  for (Object** p = start; p < end; ++p) {
1503ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ASSERT(InFromSpace(*p));
1504ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    String* target = updater_func(this, p);
150513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1506b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    if (target == NULL) continue;
150713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
150813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    ASSERT(target->IsExternalString());
150913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1510ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (InNewSpace(target)) {
151113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      // String is still in new space.  Update the table entry.
151213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      *last = target;
151313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      ++last;
151413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    } else {
151513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      // String got promoted.  Move it to the old string list.
1516ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      external_string_table_.AddOldString(target);
151713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    }
151813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
151913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
15202ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  ASSERT(last <= end);
15212ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  external_string_table_.ShrinkNewStrings(static_cast<int>(last - start));
152213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
152313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
152413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::UpdateReferencesInExternalStringTable(
1526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ExternalStringTableUpdaterCallback updater_func) {
1527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Update old space string references.
1529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (external_string_table_.old_space_strings_.length() > 0) {
15302ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    Object** start = &external_string_table_.old_space_strings_[0];
15312ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    Object** end = start + external_string_table_.old_space_strings_.length();
15322ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    for (Object** p = start; p < end; ++p) *p = updater_func(this, p);
1533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  UpdateNewSpaceReferencesInExternalStringTable(updater_func);
1536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
1537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
153941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate <class T>
154041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgstruct WeakListVisitor;
154141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
154241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
154341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate <class T>
154441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgstatic Object* VisitWeakList(Heap* heap,
154541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                             Object* list,
154641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                             WeakObjectRetainer* retainer,
154741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                             bool record_slots) {
1548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Object* undefined = heap->undefined_value();
1549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Object* head = undefined;
155041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  T* tail = NULL;
155141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  MarkCompactCollector* collector = heap->mark_compact_collector();
155241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  while (list != undefined) {
1553a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Check whether to keep the candidate in the list.
155441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    T* candidate = reinterpret_cast<T*>(list);
155541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Object* retained = retainer->RetainAs(list);
155641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (retained != NULL) {
1557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (head == undefined) {
1558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // First element in the list.
155941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        head = retained;
1560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      } else {
1561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // Subsequent elements in the list.
1562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ASSERT(tail != NULL);
156341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        WeakListVisitor<T>::SetWeakNext(tail, retained);
1564ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        if (record_slots) {
156541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          Object** next_slot =
156641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset());
156741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          collector->RecordSlot(next_slot, next_slot, retained);
1568ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        }
1569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
157041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      // Retained object is new tail.
157141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      ASSERT(!retained->IsUndefined());
157241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      candidate = reinterpret_cast<T*>(retained);
157341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      tail = candidate;
1574c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1575c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
157641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      // tail is a live object, visit it.
157741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      WeakListVisitor<T>::VisitLiveObject(
157841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          heap, tail, retainer, record_slots);
15791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else {
15801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      WeakListVisitor<T>::VisitPhantomObject(heap, candidate);
1581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Move to next element in the list.
158441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    list = WeakListVisitor<T>::WeakNext(candidate);
1585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Terminate the list if there is one or more elements.
1588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (tail != NULL) {
158941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    WeakListVisitor<T>::SetWeakNext(tail, undefined);
1590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return head;
1592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
159541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate<>
159641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgstruct WeakListVisitor<JSFunction> {
159741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static void SetWeakNext(JSFunction* function, Object* next) {
159841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    function->set_next_function_link(next);
159941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
160041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
160141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static Object* WeakNext(JSFunction* function) {
160241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return function->next_function_link();
160341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
160441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
160541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static int WeakNextOffset() {
160641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return JSFunction::kNextFunctionLinkOffset;
160741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
160841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
160941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static void VisitLiveObject(Heap*, JSFunction*,
161041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                              WeakObjectRetainer*, bool) {
161141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
16121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
16131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static void VisitPhantomObject(Heap*, JSFunction*) {
16141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
161541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org};
161641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
161741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
161841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate<>
161941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgstruct WeakListVisitor<Context> {
162041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static void SetWeakNext(Context* context, Object* next) {
162141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    context->set(Context::NEXT_CONTEXT_LINK,
162241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                 next,
162341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                 UPDATE_WRITE_BARRIER);
162441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
162541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
162641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static Object* WeakNext(Context* context) {
162741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return context->get(Context::NEXT_CONTEXT_LINK);
162841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
162941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
163041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static void VisitLiveObject(Heap* heap,
163141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                              Context* context,
163241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                              WeakObjectRetainer* retainer,
163341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                              bool record_slots) {
163441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    // Process the weak list of optimized functions for the context.
163541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Object* function_list_head =
163641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        VisitWeakList<JSFunction>(
163741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            heap,
163841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            context->get(Context::OPTIMIZED_FUNCTIONS_LIST),
163941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            retainer,
164041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            record_slots);
164141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    context->set(Context::OPTIMIZED_FUNCTIONS_LIST,
164241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                 function_list_head,
164341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                 UPDATE_WRITE_BARRIER);
164441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (record_slots) {
164541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Object** optimized_functions =
164641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          HeapObject::RawField(
164741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org              context, FixedArray::SizeFor(Context::OPTIMIZED_FUNCTIONS_LIST));
164841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      heap->mark_compact_collector()->RecordSlot(
164941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          optimized_functions, optimized_functions, function_list_head);
165041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
165141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
165241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
16531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static void VisitPhantomObject(Heap*, Context*) {
16541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
16551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
165641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static int WeakNextOffset() {
165741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK);
165841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
165941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org};
166041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
166141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
16624a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
1663ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  // We don't record weak slots during marking or scavenges.
1664ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  // Instead we do it once when we complete mark-compact cycle.
1665ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  // Note that write barrier has no effect if we are already in the middle of
1666ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  // compacting mark-sweep cycle and we have to record slots manually.
1667ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  bool record_slots =
1668ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      gc_state() == MARK_COMPACT &&
1669ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      mark_compact_collector()->is_compacting();
16701fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  ProcessArrayBuffers(retainer, record_slots);
16711fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  ProcessNativeContexts(retainer, record_slots);
1672ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  ProcessAllocationSites(retainer, record_slots);
16731fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
16741fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
16751fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid Heap::ProcessNativeContexts(WeakObjectRetainer* retainer,
16761fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                 bool record_slots) {
167741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Object* head =
167841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      VisitWeakList<Context>(
167941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          this, native_contexts_list(), retainer, record_slots);
16804a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  // Update the head of the list of contexts.
168146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  native_contexts_list_ = head;
16824a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org}
16834a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
16844a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
16851fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgtemplate<>
16861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgstruct WeakListVisitor<JSArrayBufferView> {
16871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static void SetWeakNext(JSArrayBufferView* obj, Object* next) {
16881fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    obj->set_weak_next(next);
16891fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
16901fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
16911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static Object* WeakNext(JSArrayBufferView* obj) {
16921fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    return obj->weak_next();
16931fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
16941fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
169541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static void VisitLiveObject(Heap*,
16961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                              JSArrayBufferView* obj,
16971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                              WeakObjectRetainer* retainer,
16981fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                              bool record_slots) {}
16991fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
17001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static void VisitPhantomObject(Heap*, JSArrayBufferView*) {}
17011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
170241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static int WeakNextOffset() {
17031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return JSArrayBufferView::kWeakNextOffset;
170441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
17051fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org};
17061fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
17071fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
17081fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgtemplate<>
17091fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgstruct WeakListVisitor<JSArrayBuffer> {
171041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static void SetWeakNext(JSArrayBuffer* obj, Object* next) {
17111fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    obj->set_weak_next(next);
17121fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
17131fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
171441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static Object* WeakNext(JSArrayBuffer* obj) {
17151fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    return obj->weak_next();
17161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
17171fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
171841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static void VisitLiveObject(Heap* heap,
171941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                              JSArrayBuffer* array_buffer,
17201fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                              WeakObjectRetainer* retainer,
17211fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                              bool record_slots) {
17221fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    Object* typed_array_obj =
17231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        VisitWeakList<JSArrayBufferView>(
172441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            heap,
17251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org            array_buffer->weak_first_view(),
172641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            retainer, record_slots);
17271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    array_buffer->set_weak_first_view(typed_array_obj);
172841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (typed_array_obj != heap->undefined_value() && record_slots) {
17291fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      Object** slot = HeapObject::RawField(
17301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          array_buffer, JSArrayBuffer::kWeakFirstViewOffset);
173141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj);
17321fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    }
17331fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
17341fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
17351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) {
17361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Runtime::FreeArrayBuffer(heap->isolate(), phantom);
17371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
17381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
173941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static int WeakNextOffset() {
174041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return JSArrayBuffer::kWeakNextOffset;
174141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
17421fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org};
17431fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
17441fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
17451fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer,
17461fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                               bool record_slots) {
17471fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  Object* array_buffer_obj =
174841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      VisitWeakList<JSArrayBuffer>(this,
174941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                   array_buffers_list(),
17501fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                   retainer, record_slots);
17511fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_array_buffers_list(array_buffer_obj);
17521fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
17531fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
17541fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
17551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Heap::TearDownArrayBuffers() {
17561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Object* undefined = undefined_value();
17571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  for (Object* o = array_buffers_list(); o != undefined;) {
17581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    JSArrayBuffer* buffer = JSArrayBuffer::cast(o);
17591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Runtime::FreeArrayBuffer(isolate(), buffer);
17601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    o = buffer->weak_next();
17611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
17621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  array_buffers_list_ = undefined;
17631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
17641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
17651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1766ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgtemplate<>
1767ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstruct WeakListVisitor<AllocationSite> {
1768ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  static void SetWeakNext(AllocationSite* obj, Object* next) {
1769ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    obj->set_weak_next(next);
1770ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
1771ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1772ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  static Object* WeakNext(AllocationSite* obj) {
1773ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return obj->weak_next();
1774ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
1775ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1776ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  static void VisitLiveObject(Heap* heap,
1777ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                              AllocationSite* array_buffer,
1778ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                              WeakObjectRetainer* retainer,
1779ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                              bool record_slots) {}
1780ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1781ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  static void VisitPhantomObject(Heap* heap, AllocationSite* phantom) {}
1782ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1783ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  static int WeakNextOffset() {
1784ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return AllocationSite::kWeakNextOffset;
1785ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
1786ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org};
1787ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1788ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1789ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid Heap::ProcessAllocationSites(WeakObjectRetainer* retainer,
1790ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                  bool record_slots) {
1791ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Object* allocation_site_obj =
1792ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      VisitWeakList<AllocationSite>(this,
1793ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                    allocation_sites_list(),
1794ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                    retainer, record_slots);
1795ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  set_allocation_sites_list(allocation_site_obj);
1796ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
1797ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1798ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1799f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
180079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
1801f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
18024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Both the external string table and the string table may contain
1803e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // external strings, but neither lists them exhaustively, nor is the
1804e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // intersection set empty.  Therefore we iterate over the external string
18054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // table first, ignoring internalized strings, and then over the
18064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // internalized string table.
1807e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1808e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  class ExternalStringTableVisitorAdapter : public ObjectVisitor {
1809f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com   public:
1810e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    explicit ExternalStringTableVisitorAdapter(
1811e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {}
1812e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    virtual void VisitPointers(Object** start, Object** end) {
1813e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      for (Object** p = start; p < end; p++) {
18144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        // Visit non-internalized external strings,
18154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        // since internalized strings are listed in the string table.
18164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        if (!(*p)->IsInternalizedString()) {
1817e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          ASSERT((*p)->IsExternalString());
1818e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          visitor_->VisitExternalString(Utils::ToLocal(
1819e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org              Handle<String>(String::cast(*p))));
1820e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        }
1821e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      }
1822e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
1823e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org   private:
1824e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    v8::ExternalResourceVisitor* visitor_;
1825e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } external_string_table_visitor(visitor);
1826e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1827e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  external_string_table_.Iterate(&external_string_table_visitor);
1828e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
18294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  class StringTableVisitorAdapter : public ObjectVisitor {
1830e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org   public:
18314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    explicit StringTableVisitorAdapter(
1832e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {}
1833f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    virtual void VisitPointers(Object** start, Object** end) {
1834f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      for (Object** p = start; p < end; p++) {
1835f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        if ((*p)->IsExternalString()) {
18364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          ASSERT((*p)->IsInternalizedString());
1837f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          visitor_->VisitExternalString(Utils::ToLocal(
1838f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com              Handle<String>(String::cast(*p))));
1839f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        }
1840f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      }
1841f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    }
1842f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com   private:
1843f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    v8::ExternalResourceVisitor* visitor_;
18444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } string_table_visitor(visitor);
1845e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
18464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  string_table()->IterateElements(&string_table_visitor);
1847f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
1848f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
1849f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
1850ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> {
1851ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
1852ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static inline void VisitPointer(Heap* heap, Object** p) {
1853ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    Object* object = *p;
1854ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (!heap->InNewSpace(object)) return;
1855ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p),
1856ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                         reinterpret_cast<HeapObject*>(object));
1857ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
1858ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
1859ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1860ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
186113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgAddress Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
186213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                         Address new_space_front) {
1863b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  do {
1864c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    SemiSpace::AssertValidRange(new_space_front, new_space_.top());
1865b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // The addresses new_space_front and new_space_.top() define a
1866b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // queue of unprocessed copied objects.  Process them until the
1867b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // queue is empty.
1868c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    while (new_space_front != new_space_.top()) {
1869c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (!NewSpacePage::IsAtEnd(new_space_front)) {
1870c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        HeapObject* object = HeapObject::FromAddress(new_space_front);
1871c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        new_space_front +=
1872c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          NewSpaceScavenger::IterateBody(object->map(), object);
1873c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else {
1874c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        new_space_front =
1875ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org            NewSpacePage::FromLimit(new_space_front)->next_page()->area_start();
1876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
1877b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    }
187843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1879b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // Promote and process all the to-be-promoted objects.
1880c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    {
1881c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      StoreBufferRebuildScope scope(this,
1882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                    store_buffer(),
1883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                    &ScavengeStoreBufferCallback);
1884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      while (!promotion_queue()->is_empty()) {
1885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        HeapObject* target;
1886c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        int size;
1887c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        promotion_queue()->remove(&target, &size);
1888c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1889c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Promoted object might be already partially visited
1890c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // during old space pointer iteration. Thus we search specificly
1891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // for pointers to from semispace instead of looking for pointers
1892c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // to new space.
1893c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ASSERT(!target->IsMap());
1894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        IterateAndMarkPointersToFromSpace(target->address(),
1895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                          target->address() + size,
1896c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                          &ScavengeObject);
1897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
189943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1900b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // Take another spin if there are now unswept objects in new space
1901b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // (there are currently no more unswept promoted objects).
1902c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } while (new_space_front != new_space_.top());
190343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
190413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  return new_space_front;
190543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
190643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
190743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1908ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comSTATIC_ASSERT((FixedDoubleArray::kHeaderSize & kDoubleAlignmentMask) == 0);
1909ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1910ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1911ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comINLINE(static HeapObject* EnsureDoubleAligned(Heap* heap,
1912ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                                              HeapObject* object,
1913ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                                              int size));
1914ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1915ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comstatic HeapObject* EnsureDoubleAligned(Heap* heap,
1916ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                                       HeapObject* object,
1917ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                                       int size) {
1918ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  if ((OffsetFrom(object->address()) & kDoubleAlignmentMask) != 0) {
1919ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    heap->CreateFillerObjectAt(object->address(), kPointerSize);
1920ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    return HeapObject::FromAddress(object->address() + kPointerSize);
1921ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  } else {
1922ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    heap->CreateFillerObjectAt(object->address() + size - kPointerSize,
1923ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                               kPointerSize);
1924ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    return object;
1925ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
1926ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com}
1927ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1928ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1929c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgenum LoggingAndProfiling {
1930c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  LOGGING_AND_PROFILING_ENABLED,
1931c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  LOGGING_AND_PROFILING_DISABLED
1932c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org};
1933c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
1934c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
1935c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS };
1936c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
1937c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
1938c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comtemplate<MarksHandling marks_handling,
1939c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         LoggingAndProfiling logging_and_profiling_mode>
1940ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass ScavengingVisitor : public StaticVisitorBase {
1941ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
1942ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static void Initialize() {
1943fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString);
1944ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString);
1945ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate);
1946ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitByteArray, &EvacuateByteArray);
1947ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitFixedArray, &EvacuateFixedArray);
19486d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray);
1949c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
195046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    table_.Register(kVisitNativeContext,
19514a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
1952c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                        template VisitSpecialized<Context::kSize>);
195343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1954ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitConsString,
1955ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
1956c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                        template VisitSpecialized<ConsString::kSize>);
195743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19584668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    table_.Register(kVisitSlicedString,
19594668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
19604668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org                        template VisitSpecialized<SlicedString::kSize>);
19614668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org
1962f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    table_.Register(kVisitSymbol,
1963f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
1964f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                        template VisitSpecialized<Symbol::kSize>);
1965f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
1966ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitSharedFunctionInfo,
1967ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
1968c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                        template VisitSpecialized<SharedFunctionInfo::kSize>);
196943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19707c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    table_.Register(kVisitJSWeakMap,
19717c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
19727c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                    Visit);
19737c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
1974ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    table_.Register(kVisitJSWeakSet,
1975ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
1976ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                    Visit);
1977ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
19781fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    table_.Register(kVisitJSArrayBuffer,
19791fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
19801fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                    Visit);
19811fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
19821fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    table_.Register(kVisitJSTypedArray,
19831fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
19841fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                    Visit);
19851fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
19861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    table_.Register(kVisitJSDataView,
19871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
19881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                    Visit);
19891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1990ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    table_.Register(kVisitJSRegExp,
1991ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
1992ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                    Visit);
1993ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
1994c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (marks_handling == IGNORE_MARKS) {
1995c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      table_.Register(kVisitJSFunction,
1996c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      &ObjectEvacuationStrategy<POINTER_OBJECT>::
1997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          template VisitSpecialized<JSFunction::kSize>);
1998c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
1999c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      table_.Register(kVisitJSFunction, &EvacuateJSFunction);
2000c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
20010b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
2002ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>,
2003ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                   kVisitDataObject,
2004ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                   kVisitDataObjectGeneric>();
200543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2006ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>,
2007ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                   kVisitJSObject,
2008ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                   kVisitJSObjectGeneric>();
200943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2010ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>,
2011ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                   kVisitStruct,
2012ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                   kVisitStructGeneric>();
2013ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
201443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2015c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  static VisitorDispatchTable<ScavengingCallback>* GetTable() {
2016c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return &table_;
2017ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
20186a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2019ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org private:
2020ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  enum ObjectContents  { DATA_OBJECT, POINTER_OBJECT };
20216a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2022ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static void RecordCopiedObject(Heap* heap, HeapObject* obj) {
2023ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    bool should_record = false;
2024ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org#ifdef DEBUG
2025ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    should_record = FLAG_heap_stats;
2026ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org#endif
2027ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    should_record = should_record || FLAG_log_gc;
2028ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    if (should_record) {
2029ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      if (heap->new_space()->Contains(obj)) {
2030ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        heap->new_space()->RecordAllocation(obj);
20316a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org      } else {
2032ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        heap->new_space()->RecordPromotion(obj);
20336a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org      }
20346a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    }
20356a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
20365a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
2037ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // Helper function used by CopyObject to copy a source object to an
2038ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // allocated target object and update the forwarding pointer in the source
2039ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // object.  Returns the target object.
20401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  INLINE(static void MigrateObject(Heap* heap,
20411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                   HeapObject* source,
20421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                   HeapObject* target,
20431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                   int size)) {
2044ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    // Copy the content of source to target.
2045ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    heap->CopyBlock(target->address(), source->address(), size);
20465a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
2047ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    // Set the forwarding address.
2048ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    source->set_map_word(MapWord::FromForwardingAddress(target));
20496a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2050c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) {
2051c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      // Update NewSpace stats if necessary.
2052c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RecordCopiedObject(heap, target);
2053c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address()));
2054c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      Isolate* isolate = heap->isolate();
2055355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      if (isolate->logger()->is_logging_code_events() ||
2056f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          isolate->cpu_profiler()->is_profiling()) {
2057c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        if (target->IsSharedFunctionInfo()) {
2058c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org          PROFILE(isolate, SharedFunctionInfoMoveEvent(
2059c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org              source->address(), target->address()));
2060c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        }
20614a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org      }
2062c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
2063c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (marks_handling == TRANSFER_MARKS) {
2065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (Marking::TransferColor(source, target)) {
20662efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        MemoryChunk::IncrementLiveBytesFromGC(target->address(), size);
2067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
2068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
2069ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
20706a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2071ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
2072594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  template<ObjectContents object_contents, int alignment>
2073ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static inline void EvacuateObject(Map* map,
2074ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                    HeapObject** slot,
2075ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                    HeapObject* object,
2076ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                    int object_size) {
2077594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    SLOW_ASSERT(object_size <= Page::kMaxNonCodeHeapObjectSize);
2078394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    SLOW_ASSERT(object->Size() == object_size);
20796a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2080ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    int allocation_size = object_size;
2081ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (alignment != kObjectAlignment) {
2082ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      ASSERT(alignment == kDoubleAlignment);
2083ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      allocation_size += kPointerSize;
2084ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
2085ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
2086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Heap* heap = map->GetHeap();
2087ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (heap->ShouldBePromoted(object->address(), object_size)) {
2088303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      MaybeObject* maybe_result;
20896a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2090594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (object_contents == DATA_OBJECT) {
2091db6d1aeaeb171233a6b1b34243387148e0068194mstarzinger@chromium.org        // TODO(mstarzinger): Turn this check into a regular assert soon!
2092db6d1aeaeb171233a6b1b34243387148e0068194mstarzinger@chromium.org        CHECK(heap->AllowedToBeMigrated(object, OLD_DATA_SPACE));
2093594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        maybe_result = heap->old_data_space()->AllocateRaw(allocation_size);
2094ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      } else {
2095db6d1aeaeb171233a6b1b34243387148e0068194mstarzinger@chromium.org        // TODO(mstarzinger): Turn this check into a regular assert soon!
2096db6d1aeaeb171233a6b1b34243387148e0068194mstarzinger@chromium.org        CHECK(heap->AllowedToBeMigrated(object, OLD_POINTER_SPACE));
2097db6d1aeaeb171233a6b1b34243387148e0068194mstarzinger@chromium.org        maybe_result = heap->old_pointer_space()->AllocateRaw(allocation_size);
2098ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      }
20996a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2100303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      Object* result = NULL;  // Initialization to please compiler.
2101303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (maybe_result->ToObject(&result)) {
2102ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        HeapObject* target = HeapObject::cast(result);
21031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
2104ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        if (alignment != kObjectAlignment) {
2105ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          target = EnsureDoubleAligned(heap, target, allocation_size);
2106ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        }
2107ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
21081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // Order is important: slot might be inside of the target if target
21091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // was allocated over a dead object and slot comes from the store
21101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // buffer.
21111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        *slot = target;
21121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        MigrateObject(heap, object, target, object_size);
21136a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2114ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        if (object_contents == POINTER_OBJECT) {
2115ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          if (map->instance_type() == JS_FUNCTION_TYPE) {
2116ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com            heap->promotion_queue()->insert(
2117ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                target, JSFunction::kNonWeakFieldsEndOffset);
2118ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          } else {
2119ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com            heap->promotion_queue()->insert(target, object_size);
2120ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          }
2121ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        }
21226a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        heap->tracer()->increment_promoted_objects_size(object_size);
2124ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        return;
21256a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org      }
2126ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    }
2127db6d1aeaeb171233a6b1b34243387148e0068194mstarzinger@chromium.org    // TODO(mstarzinger): Turn this check into a regular assert soon!
2128db6d1aeaeb171233a6b1b34243387148e0068194mstarzinger@chromium.org    CHECK(heap->AllowedToBeMigrated(object, NEW_SPACE));
2129ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    MaybeObject* allocation = heap->new_space()->AllocateRaw(allocation_size);
2130c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    heap->promotion_queue()->SetNewLimit(heap->new_space()->top());
2131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* result = allocation->ToObjectUnchecked();
21321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    HeapObject* target = HeapObject::cast(result);
2133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2134ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (alignment != kObjectAlignment) {
2135ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      target = EnsureDoubleAligned(heap, target, allocation_size);
2136ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
2137ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
21381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Order is important: slot might be inside of the target if target
21391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // was allocated over a dead object and slot comes from the store
21401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // buffer.
21411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    *slot = target;
21421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    MigrateObject(heap, object, target, object_size);
2143ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    return;
2144ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
21456a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21466a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static inline void EvacuateJSFunction(Map* map,
2148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                        HeapObject** slot,
2149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                        HeapObject* object) {
2150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ObjectEvacuationStrategy<POINTER_OBJECT>::
2151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        template VisitSpecialized<JSFunction::kSize>(map, slot, object);
2152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    HeapObject* target = *slot;
2154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(target);
2155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (Marking::IsBlack(mark_bit)) {
2156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // This object is black and it might not be rescanned by marker.
2157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // We should explicitly record code entry slot for compaction because
2158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // promotion queue processing (IterateAndMarkPointersToFromSpace) will
2159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // miss it as it is not HeapObject-tagged.
2160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Address code_entry_slot =
2161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          target->address() + JSFunction::kCodeEntryOffset;
2162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot));
2163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      map->GetHeap()->mark_compact_collector()->
2164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          RecordCodeEntrySlot(code_entry_slot, code);
2165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
2166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
2167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2169ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static inline void EvacuateFixedArray(Map* map,
2170ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                        HeapObject** slot,
2171ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                        HeapObject* object) {
2172ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    int object_size = FixedArray::BodyDescriptor::SizeOf(map, object);
2173594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    EvacuateObject<POINTER_OBJECT, kObjectAlignment>(
2174594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        map, slot, object, object_size);
21756a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
21766a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21776a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21786d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  static inline void EvacuateFixedDoubleArray(Map* map,
21796d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                              HeapObject** slot,
21806d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                              HeapObject* object) {
21816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
21826d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int object_size = FixedDoubleArray::SizeFor(length);
2183594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    EvacuateObject<DATA_OBJECT, kDoubleAlignment>(
2184594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        map, slot, object, object_size);
21856d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
21866d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
21876d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
2188ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static inline void EvacuateByteArray(Map* map,
2189ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                       HeapObject** slot,
2190ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                       HeapObject* object) {
2191ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize();
2192594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    EvacuateObject<DATA_OBJECT, kObjectAlignment>(
2193ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        map, slot, object, object_size);
2194ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
21956a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21966a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2197fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  static inline void EvacuateSeqOneByteString(Map* map,
21986a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org                                            HeapObject** slot,
21996a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org                                            HeapObject* object) {
2200fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    int object_size = SeqOneByteString::cast(object)->
2201fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        SeqOneByteStringSize(map->instance_type());
2202594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    EvacuateObject<DATA_OBJECT, kObjectAlignment>(
2203ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        map, slot, object, object_size);
2204ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
22056a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22066a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2207ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static inline void EvacuateSeqTwoByteString(Map* map,
2208ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                              HeapObject** slot,
2209ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                              HeapObject* object) {
2210ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    int object_size = SeqTwoByteString::cast(object)->
2211ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        SeqTwoByteStringSize(map->instance_type());
2212594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    EvacuateObject<DATA_OBJECT, kObjectAlignment>(
2213ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        map, slot, object, object_size);
2214ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
22156a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22165a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
2217ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static inline bool IsShortcutCandidate(int type) {
2218ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    return ((type & kShortcutTypeMask) == kShortcutTypeTag);
2219ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
22206a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2221ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static inline void EvacuateShortcutCandidate(Map* map,
2222ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                               HeapObject** slot,
2223ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                               HeapObject* object) {
2224ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    ASSERT(IsShortcutCandidate(map->instance_type()));
22256a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Heap* heap = map->GetHeap();
2227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (marks_handling == IGNORE_MARKS &&
2229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ConsString::cast(object)->unchecked_second() ==
2230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        heap->empty_string()) {
2231ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      HeapObject* first =
2232ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org          HeapObject::cast(ConsString::cast(object)->unchecked_first());
22336a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2234ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      *slot = first;
22356a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (!heap->InNewSpace(first)) {
2237ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        object->set_map_word(MapWord::FromForwardingAddress(first));
2238ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        return;
2239ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      }
22406a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2241ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      MapWord first_word = first->map_word();
2242ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      if (first_word.IsForwardingAddress()) {
2243ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        HeapObject* target = first_word.ToForwardingAddress();
2244ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
2245ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        *slot = target;
2246ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        object->set_map_word(MapWord::FromForwardingAddress(target));
2247ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        return;
2248ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      }
2249ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
2250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      heap->DoScavengeObject(first->map(), slot, first);
2251ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      object->set_map_word(MapWord::FromForwardingAddress(*slot));
225243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
225343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
22546a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2255ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    int object_size = ConsString::kSize;
2256594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    EvacuateObject<POINTER_OBJECT, kObjectAlignment>(
2257ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        map, slot, object, object_size);
225843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
225943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2260ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  template<ObjectContents object_contents>
2261ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  class ObjectEvacuationStrategy {
2262ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org   public:
2263ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    template<int object_size>
2264ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    static inline void VisitSpecialized(Map* map,
2265ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                        HeapObject** slot,
2266ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                        HeapObject* object) {
2267594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      EvacuateObject<object_contents, kObjectAlignment>(
2268ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          map, slot, object, object_size);
226943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
22706a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2271ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    static inline void Visit(Map* map,
2272ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                             HeapObject** slot,
2273ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                             HeapObject* object) {
2274ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      int object_size = map->instance_size();
2275594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      EvacuateObject<object_contents, kObjectAlignment>(
2276ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          map, slot, object, object_size);
2277ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    }
2278ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  };
22796a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2280c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  static VisitorDispatchTable<ScavengingCallback> table_;
2281ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
22826a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22836a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comtemplate<MarksHandling marks_handling,
2285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         LoggingAndProfiling logging_and_profiling_mode>
2286c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgVisitorDispatchTable<ScavengingCallback>
2287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ScavengingVisitor<marks_handling, logging_and_profiling_mode>::table_;
2288c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2289c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2290c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgstatic void InitializeScavengingVisitorsTables() {
2291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ScavengingVisitor<TRANSFER_MARKS,
2292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                    LOGGING_AND_PROFILING_DISABLED>::Initialize();
2293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::Initialize();
2294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ScavengingVisitor<TRANSFER_MARKS,
2295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                    LOGGING_AND_PROFILING_ENABLED>::Initialize();
2296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize();
2297c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
2298c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2299c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::SelectScavengingVisitorsTable() {
2301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool logging_and_profiling =
2302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      isolate()->logger()->is_logging() ||
2303f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      isolate()->cpu_profiler()->is_profiling() ||
2304c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      (isolate()->heap_profiler() != NULL &&
2305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       isolate()->heap_profiler()->is_profiling());
2306c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!incremental_marking()->IsMarking()) {
2308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!logging_and_profiling) {
2309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      scavenging_visitors_table_.CopyFrom(
2310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          ScavengingVisitor<IGNORE_MARKS,
2311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            LOGGING_AND_PROFILING_DISABLED>::GetTable());
2312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
2313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      scavenging_visitors_table_.CopyFrom(
2314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          ScavengingVisitor<IGNORE_MARKS,
2315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            LOGGING_AND_PROFILING_ENABLED>::GetTable());
2316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
2317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
2318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!logging_and_profiling) {
2319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      scavenging_visitors_table_.CopyFrom(
2320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          ScavengingVisitor<TRANSFER_MARKS,
2321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            LOGGING_AND_PROFILING_DISABLED>::GetTable());
2322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
2323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      scavenging_visitors_table_.CopyFrom(
2324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          ScavengingVisitor<TRANSFER_MARKS,
2325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            LOGGING_AND_PROFILING_ENABLED>::GetTable());
2326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
2327a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
2328a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    if (incremental_marking()->IsCompacting()) {
2329a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      // When compacting forbid short-circuiting of cons-strings.
2330a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      // Scavenging code relies on the fact that new space object
2331a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      // can't be evacuated into evacuation candidate but
2332a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      // short-circuiting violates this assumption.
2333a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      scavenging_visitors_table_.Register(
2334a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org          StaticVisitorBase::kVisitShortcutCandidate,
2335a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org          scavenging_visitors_table_.GetVisitorById(
2336a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org              StaticVisitorBase::kVisitConsString));
2337a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    }
2338c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
2339c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
23406a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23416a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23426a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgvoid Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) {
2343394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  SLOW_ASSERT(HEAP->InFromSpace(object));
23446a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  MapWord first_word = object->map_word();
2345394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  SLOW_ASSERT(!first_word.IsForwardingAddress());
23466a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  Map* map = first_word.ToMap();
2347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  map->GetHeap()->DoScavengeObject(map, p, object);
23485a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
23495a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
23505a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
2351303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocatePartialMap(InstanceType instance_type,
2352303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                      int instance_size) {
2353303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
235446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  MaybeObject* maybe_result = AllocateRawMap();
235546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (!maybe_result->ToObject(&result)) return maybe_result;
235643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
235743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Map::cast cannot be used due to uninitialized map field.
235868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map());
235943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reinterpret_cast<Map*>(result)->set_instance_type(instance_type);
236043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reinterpret_cast<Map*>(result)->set_instance_size(instance_size);
2361ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  reinterpret_cast<Map*>(result)->set_visitor_id(
2362ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        StaticVisitorBase::GetVisitorId(instance_type, instance_size));
23637c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  reinterpret_cast<Map*>(result)->set_inobject_properties(0);
2364b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  reinterpret_cast<Map*>(result)->set_pre_allocated_property_fields(0);
236543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
2366b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  reinterpret_cast<Map*>(result)->set_bit_field(0);
2367b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  reinterpret_cast<Map*>(result)->set_bit_field2(0);
236806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  int bit_field3 = Map::EnumLengthBits::encode(Map::kInvalidEnumCache) |
236906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org                   Map::OwnsDescriptors::encode(true);
237006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3);
237143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
237243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
237343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
237443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comMaybeObject* Heap::AllocateMap(InstanceType instance_type,
2376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               int instance_size,
2377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               ElementsKind elements_kind) {
2378303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
2379304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  MaybeObject* maybe_result = AllocateRawMap();
2380304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  if (!maybe_result->To(&result)) return maybe_result;
238143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
238243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Map* map = reinterpret_cast<Map*>(result);
238364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  map->set_map_no_write_barrier(meta_map());
238443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map->set_instance_type(instance_type);
2385ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  map->set_visitor_id(
2386ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      StaticVisitorBase::GetVisitorId(instance_type, instance_size));
238727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  map->set_prototype(null_value(), SKIP_WRITE_BARRIER);
238827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  map->set_constructor(null_value(), SKIP_WRITE_BARRIER);
238943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map->set_instance_size(instance_size);
23907c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  map->set_inobject_properties(0);
2391911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  map->set_pre_allocated_property_fields(0);
239227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
23932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  map->set_dependent_code(DependentCode::cast(empty_fixed_array()),
23942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                          SKIP_WRITE_BARRIER);
239581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  map->init_back_pointer(undefined_value());
239643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map->set_unused_property_fields(0);
239789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  map->set_instance_descriptors(empty_descriptor_array());
239843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map->set_bit_field(0);
2399d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  map->set_bit_field2(1 << Map::kIsExtensible);
240006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  int bit_field3 = Map::EnumLengthBits::encode(Map::kInvalidEnumCache) |
240106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org                   Map::OwnsDescriptors::encode(true);
2402355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  map->set_bit_field3(bit_field3);
2403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  map->set_elements_kind(elements_kind);
2404846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org
240543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return map;
240643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
240743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
240843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2409303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateCodeCache() {
24109a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  CodeCache* code_cache;
24119a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  { MaybeObject* maybe_code_cache = AllocateStruct(CODE_CACHE_TYPE);
24129a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org    if (!maybe_code_cache->To(&code_cache)) return maybe_code_cache;
2413303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
241427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  code_cache->set_default_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
241527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  code_cache->set_normal_type_cache(undefined_value(), SKIP_WRITE_BARRIER);
2416ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return code_cache;
2417ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
2418ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
2419ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
2420e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgMaybeObject* Heap::AllocatePolymorphicCodeCache() {
2421e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE);
2422e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org}
2423e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
2424e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
2425f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comMaybeObject* Heap::AllocateAccessorPair() {
24269a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  AccessorPair* accessors;
24279a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  { MaybeObject* maybe_accessors = AllocateStruct(ACCESSOR_PAIR_TYPE);
24289a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org    if (!maybe_accessors->To(&accessors)) return maybe_accessors;
2429f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  }
24309a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  accessors->set_getter(the_hole_value(), SKIP_WRITE_BARRIER);
24319a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  accessors->set_setter(the_hole_value(), SKIP_WRITE_BARRIER);
2432f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  return accessors;
2433f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
2434f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
2435f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
2436f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgMaybeObject* Heap::AllocateTypeFeedbackInfo() {
2437f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  TypeFeedbackInfo* info;
24389a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  { MaybeObject* maybe_info = AllocateStruct(TYPE_FEEDBACK_INFO_TYPE);
24399a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org    if (!maybe_info->To(&info)) return maybe_info;
2440f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
244146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  info->initialize_storage();
2442f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  info->set_type_feedback_cells(TypeFeedbackCells::cast(empty_fixed_array()),
2443f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org                                SKIP_WRITE_BARRIER);
2444f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return info;
2445f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
2446f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
2447f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
2448ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.orgMaybeObject* Heap::AllocateAliasedArgumentsEntry(int aliased_context_slot) {
2449ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  AliasedArgumentsEntry* entry;
24509a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  { MaybeObject* maybe_entry = AllocateStruct(ALIASED_ARGUMENTS_ENTRY_TYPE);
24519a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org    if (!maybe_entry->To(&entry)) return maybe_entry;
2452ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  }
2453ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  entry->set_aliased_context_slot(aliased_context_slot);
2454ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  return entry;
2455ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org}
2456ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org
2457ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org
245868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgconst Heap::StringTypeTable Heap::string_type_table[] = {
245968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org#define STRING_TYPE_ELEMENT(type, size, name, camel_name)                      \
246068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  {type, size, k##camel_name##MapRootIndex},
246168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  STRING_TYPE_LIST(STRING_TYPE_ELEMENT)
246268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org#undef STRING_TYPE_ELEMENT
246368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org};
246468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
246568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
24664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgconst Heap::ConstantStringTable Heap::constant_string_table[] = {
24674a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org#define CONSTANT_STRING_ELEMENT(name, contents)                                \
246868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  {contents, k##name##RootIndex},
24694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT)
24704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org#undef CONSTANT_STRING_ELEMENT
247168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org};
247268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
247368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
247468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgconst Heap::StructTable Heap::struct_table[] = {
247568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org#define STRUCT_TABLE_ELEMENT(NAME, Name, name)                                 \
247668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex },
247768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  STRUCT_LIST(STRUCT_TABLE_ELEMENT)
247868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org#undef STRUCT_TABLE_ELEMENT
247968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org};
248068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
248168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
248243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::CreateInitialMaps() {
2483303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* obj;
2484303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocatePartialMap(MAP_TYPE, Map::kSize);
2485303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2486303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
248743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Map::cast cannot be used due to uninitialized map field.
248868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  Map* new_meta_map = reinterpret_cast<Map*>(obj);
248968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_meta_map(new_meta_map);
249068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  new_meta_map->set_map(new_meta_map);
249143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2492303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
2493303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocatePartialMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2494303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2495303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
249668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_fixed_array_map(Map::cast(obj));
249743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2498303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocatePartialMap(ODDBALL_TYPE, Oddball::kSize);
2499303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2500303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
250168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_oddball_map(Map::cast(obj));
250243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25035d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Allocate the empty array.
2504303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateEmptyFixedArray();
2505303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2506303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
250768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_empty_fixed_array(FixedArray::cast(obj));
250843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
2510303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2511303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2512a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_null_value(Oddball::cast(obj));
2513ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Oddball::cast(obj)->set_kind(Oddball::kNull);
251443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2515a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
2516a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2517a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  }
2518a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_undefined_value(Oddball::cast(obj));
2519a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Oddball::cast(obj)->set_kind(Oddball::kUndefined);
2520a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  ASSERT(!InNewSpace(undefined_value()));
2521a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
2522defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  // Allocate the empty descriptor array.
2523303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateEmptyFixedArray();
2524303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2525303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2526defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  set_empty_descriptor_array(DescriptorArray::cast(obj));
252743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Fix the instance_descriptors for the existing maps.
252943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  meta_map()->set_code_cache(empty_fixed_array());
25302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  meta_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
253181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  meta_map()->init_back_pointer(undefined_value());
253289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  meta_map()->set_instance_descriptors(empty_descriptor_array());
253343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
253443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  fixed_array_map()->set_code_cache(empty_fixed_array());
25352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  fixed_array_map()->set_dependent_code(
25362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      DependentCode::cast(empty_fixed_array()));
253781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  fixed_array_map()->init_back_pointer(undefined_value());
253889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  fixed_array_map()->set_instance_descriptors(empty_descriptor_array());
253943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
254043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  oddball_map()->set_code_cache(empty_fixed_array());
25412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  oddball_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
254281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  oddball_map()->init_back_pointer(undefined_value());
254389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  oddball_map()->set_instance_descriptors(empty_descriptor_array());
254443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
254543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fix prototype object for existing maps.
254643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  meta_map()->set_prototype(null_value());
254743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  meta_map()->set_constructor(null_value());
254843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
254943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  fixed_array_map()->set_prototype(null_value());
255043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  fixed_array_map()->set_constructor(null_value());
2551defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
255243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  oddball_map()->set_prototype(null_value());
255343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  oddball_map()->set_constructor(null_value());
255443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2555303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
2556303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2557303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2558303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
25590b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  set_fixed_cow_array_map(Map::cast(obj));
25600b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  ASSERT(fixed_array_map() != fixed_cow_array_map());
25610b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
25624acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  { MaybeObject* maybe_obj =
25634acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
25644acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
25654acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
2566c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  set_scope_info_map(Map::cast(obj));
25674acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
2568303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(HEAP_NUMBER_TYPE, HeapNumber::kSize);
2569303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2570303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
257168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_heap_number_map(Map::cast(obj));
257243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  { MaybeObject* maybe_obj = AllocateMap(SYMBOL_TYPE, Symbol::kSize);
25744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
25754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
25764a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  set_symbol_map(Map::cast(obj));
25774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
2578ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  { MaybeObject* maybe_obj = AllocateMap(FOREIGN_TYPE, Foreign::kSize);
2579303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2580303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2581ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  set_foreign_map(Map::cast(obj));
258243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
258368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  for (unsigned i = 0; i < ARRAY_SIZE(string_type_table); i++) {
258468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    const StringTypeTable& entry = string_type_table[i];
2585303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    { MaybeObject* maybe_obj = AllocateMap(entry.type, entry.size);
2586303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_obj->ToObject(&obj)) return false;
2587303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
258868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    roots_[entry.index] = Map::cast(obj);
258968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  }
259043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2591303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(STRING_TYPE, kVariableSizeSentinel);
2592303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2593303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2594ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  set_undetectable_string_map(Map::cast(obj));
259568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  Map::cast(obj)->set_is_undetectable();
259643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2597303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
2598303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateMap(ASCII_STRING_TYPE, kVariableSizeSentinel);
2599303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2600303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2601ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  set_undetectable_ascii_string_map(Map::cast(obj));
260268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  Map::cast(obj)->set_is_undetectable();
260343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2604303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
26056d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        AllocateMap(FIXED_DOUBLE_ARRAY_TYPE, kVariableSizeSentinel);
26066d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
26076d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
26086d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  set_fixed_double_array_map(Map::cast(obj));
26096d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
26106d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  { MaybeObject* maybe_obj =
2611303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel);
2612303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2613303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
261468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_byte_array_map(Map::cast(obj));
261543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  { MaybeObject* maybe_obj =
2617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        AllocateMap(FREE_SPACE_TYPE, kVariableSizeSentinel);
2618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!maybe_obj->ToObject(&obj)) return false;
2619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
2620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  set_free_space_map(Map::cast(obj));
2621c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2622a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  { MaybeObject* maybe_obj = AllocateByteArray(0, TENURED);
2623a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2624a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  set_empty_byte_array(ByteArray::cast(obj));
2626a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2627303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
26284d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org        AllocateMap(EXTERNAL_PIXEL_ARRAY_TYPE, ExternalArray::kAlignedSize);
2629303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2630303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
26314d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  set_external_pixel_array_map(Map::cast(obj));
26320b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
2633303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_BYTE_ARRAY_TYPE,
2634303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         ExternalArray::kAlignedSize);
2635303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2636303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
26373811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  set_external_byte_array_map(Map::cast(obj));
26383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
2639303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE,
2640303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         ExternalArray::kAlignedSize);
2641303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2642303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
26433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  set_external_unsigned_byte_array_map(Map::cast(obj));
26443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
2645303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_SHORT_ARRAY_TYPE,
2646303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         ExternalArray::kAlignedSize);
2647303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2648303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
26493811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  set_external_short_array_map(Map::cast(obj));
26503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
2651303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE,
2652303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         ExternalArray::kAlignedSize);
2653303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2654303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
26553811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  set_external_unsigned_short_array_map(Map::cast(obj));
26563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
2657303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_INT_ARRAY_TYPE,
2658303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         ExternalArray::kAlignedSize);
2659303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2660303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
26613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  set_external_int_array_map(Map::cast(obj));
26623811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
2663303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_UNSIGNED_INT_ARRAY_TYPE,
2664303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         ExternalArray::kAlignedSize);
2665303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2666303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
26673811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  set_external_unsigned_int_array_map(Map::cast(obj));
26683811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
2669303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_FLOAT_ARRAY_TYPE,
2670303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         ExternalArray::kAlignedSize);
2671303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2672303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
26733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  set_external_float_array_map(Map::cast(obj));
26743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
26757b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  { MaybeObject* maybe_obj =
26767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
26777b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
26787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
26797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  set_non_strict_arguments_elements_map(Map::cast(obj));
26807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
26813847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_DOUBLE_ARRAY_TYPE,
26823847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com                                         ExternalArray::kAlignedSize);
26833847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    if (!maybe_obj->ToObject(&obj)) return false;
26843847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
26853847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  set_external_double_array_map(Map::cast(obj));
26863847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
26874e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  { MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalByteArray);
26884e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
26894e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
26904e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_empty_external_byte_array(ExternalArray::cast(obj));
26914e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
26924e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  { MaybeObject* maybe_obj =
26934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org        AllocateEmptyExternalArray(kExternalUnsignedByteArray);
26944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
26954e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
26964e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_empty_external_unsigned_byte_array(ExternalArray::cast(obj));
26974e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
26984e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  { MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalShortArray);
26994e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
27004e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
27014e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_empty_external_short_array(ExternalArray::cast(obj));
27024e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
27034e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  { MaybeObject* maybe_obj = AllocateEmptyExternalArray(
27044e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      kExternalUnsignedShortArray);
27054e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
27064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
27074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_empty_external_unsigned_short_array(ExternalArray::cast(obj));
27084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
27094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  { MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalIntArray);
27104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
27114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
27124e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_empty_external_int_array(ExternalArray::cast(obj));
27134e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
27144e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  { MaybeObject* maybe_obj =
27154e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org        AllocateEmptyExternalArray(kExternalUnsignedIntArray);
27164e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
27174e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
27184e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_empty_external_unsigned_int_array(ExternalArray::cast(obj));
27194e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
27204e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  { MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalFloatArray);
27214e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
27224e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
27234e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_empty_external_float_array(ExternalArray::cast(obj));
27244e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
27254e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  { MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalDoubleArray);
27264e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
27274e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
27284e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_empty_external_double_array(ExternalArray::cast(obj));
27294e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
27304e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  { MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalPixelArray);
27314e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
27324e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
27334e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_empty_external_pixel_array(ExternalArray::cast(obj));
27344e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
2735303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(CODE_TYPE, kVariableSizeSentinel);
2736303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2737303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
273868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_code_map(Map::cast(obj));
273943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
274041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  { MaybeObject* maybe_obj = AllocateMap(CELL_TYPE, Cell::kSize);
274141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
274241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
274341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  set_cell_map(Map::cast(obj));
274441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
274541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  { MaybeObject* maybe_obj = AllocateMap(PROPERTY_CELL_TYPE,
2746b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                         PropertyCell::kSize);
2747303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2748303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2749defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  set_global_property_cell_map(Map::cast(obj));
2750defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
2751303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(FILLER_TYPE, kPointerSize);
2752303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2753303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2754defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  set_one_pointer_filler_map(Map::cast(obj));
275543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2756303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(FILLER_TYPE, 2 * kPointerSize);
2757303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2758303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2759defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  set_two_pointer_filler_map(Map::cast(obj));
276043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
276168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  for (unsigned i = 0; i < ARRAY_SIZE(struct_table); i++) {
276268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    const StructTable& entry = struct_table[i];
2763303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    { MaybeObject* maybe_obj = AllocateMap(entry.type, entry.size);
2764303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_obj->ToObject(&obj)) return false;
2765303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
276668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    roots_[entry.index] = Map::cast(obj);
276768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  }
276843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2769303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
2770303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2771303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2772303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
277368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_hash_table_map(Map::cast(obj));
277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2775303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
2776303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2777303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2778303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
27796d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  set_function_context_map(Map::cast(obj));
278043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2781303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
2782303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2783303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2784303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
278568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_catch_context_map(Map::cast(obj));
278637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
2787303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
2788303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2789303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2790303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
27916d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  set_with_context_map(Map::cast(obj));
27926d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
27936d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  { MaybeObject* maybe_obj =
27946d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
27956d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
27966d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
27974acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  set_block_context_map(Map::cast(obj));
27984acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
27994acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  { MaybeObject* maybe_obj =
28004acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
28014acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
28024acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
2803f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  set_module_context_map(Map::cast(obj));
2804f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
2805f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  { MaybeObject* maybe_obj =
2806f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2807f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2808f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
280946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  set_global_context_map(Map::cast(obj));
281046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
281146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  { MaybeObject* maybe_obj =
281246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
281346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
281446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
281546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Map* native_context_map = Map::cast(obj);
281646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  native_context_map->set_dictionary_map(true);
281746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  native_context_map->set_visitor_id(StaticVisitorBase::kVisitNativeContext);
281846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  set_native_context_map(native_context_map);
281943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2820303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(SHARED_FUNCTION_INFO_TYPE,
2821303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         SharedFunctionInfo::kAlignedSize);
2822303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2823303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
282468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_shared_function_info_map(Map::cast(obj));
282543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
282631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  { MaybeObject* maybe_obj = AllocateMap(JS_MESSAGE_OBJECT_TYPE,
282731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org                                         JSMessageObject::kSize);
282831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
282931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  }
283031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  set_message_object_map(Map::cast(obj));
283131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
2832eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  Map* external_map;
2833eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  { MaybeObject* maybe_obj =
2834eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org        AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
2835eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org    if (!maybe_obj->To(&external_map)) return false;
2836eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  }
2837eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  external_map->set_is_extensible(false);
2838eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  set_external_map(external_map);
2839eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org
2840ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(!InNewSpace(empty_fixed_array()));
284143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
284243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
284343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
284443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2845303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) {
284643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Statically ensure that it is safe to allocate heap numbers in paged
284743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // spaces.
2848ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  STATIC_ASSERT(HeapNumber::kSize <= Page::kNonCodeObjectAreaSize);
28499258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
2850c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
2851303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
2852303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result =
2853303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateRaw(HeapNumber::kSize, space, OLD_DATA_SPACE);
2854303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
2855303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
285643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
285764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(heap_number_map());
285843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapNumber::cast(result)->set_value(value);
285943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
286043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
286143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
286243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2863303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateHeapNumber(double value) {
28649bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // Use general version, if we're forced to always allocate.
2865c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  if (always_allocate()) return AllocateHeapNumber(value, TENURED);
2866c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
286743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // This version of AllocateHeapNumber is optimized for
286843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // allocation in new space.
2869ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxNonCodeHeapObjectSize);
2870303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
2871303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = new_space_.AllocateRaw(HeapNumber::kSize);
2872303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
2873303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
287464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(heap_number_map());
287543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapNumber::cast(result)->set_value(value);
287643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
287743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
287843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
287943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
288041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgMaybeObject* Heap::AllocateCell(Object* value) {
2881303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
2882303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = AllocateRawCell();
2883303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
2884303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
288541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(cell_map());
288641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Cell::cast(result)->set_value(value);
288741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return result;
288841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
288941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
289041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
2891b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgMaybeObject* Heap::AllocatePropertyCell(Object* value) {
289241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Object* result;
2893e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  MaybeObject* maybe_result = AllocateRawPropertyCell();
2894e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (!maybe_result->ToObject(&result)) return maybe_result;
2895e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
289664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(
289764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      global_property_cell_map());
28981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  PropertyCell* cell = PropertyCell::cast(result);
28991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  cell->set_dependent_code(DependentCode::cast(empty_fixed_array()),
29001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                           SKIP_WRITE_BARRIER);
29011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  cell->set_value(value);
29021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  cell->set_type(Type::None());
2903e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  maybe_result = cell->SetValueInferType(value);
2904e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (maybe_result->IsFailure()) return maybe_result;
29052abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  return result;
29062abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
29072abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
29082abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
29091fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgMaybeObject* Heap::AllocateBox(Object* value, PretenureFlag pretenure) {
29101fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  Box* result;
29111fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  MaybeObject* maybe_result = AllocateStruct(BOX_TYPE);
29121fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  if (!maybe_result->To(&result)) return maybe_result;
29131fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  result->set_value(value);
29141fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  return result;
29151fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
29161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
29171fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
2918bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgMaybeObject* Heap::AllocateAllocationSite() {
2919bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Object* result;
2920bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  MaybeObject* maybe_result = Allocate(allocation_site_map(),
2921bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                       OLD_POINTER_SPACE);
2922bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (!maybe_result->ToObject(&result)) return maybe_result;
2923ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  AllocationSite* site = AllocationSite::cast(result);
2924ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  site->Initialize();
2925ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
2926ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Link the site
2927ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  site->set_weak_next(allocation_sites_list());
2928ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  set_allocation_sites_list(site);
2929bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  return result;
2930bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
2931bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
2932bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
2933303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::CreateOddball(const char* to_string,
2934ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 Object* to_number,
2935ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 byte kind) {
2936303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
2937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  { MaybeObject* maybe_result = Allocate(oddball_map(), OLD_POINTER_SPACE);
2938303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
2939303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2940ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return Oddball::cast(result)->Initialize(to_string, to_number, kind);
294143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
294243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
294343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
294443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::CreateApiObjects() {
294543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* obj;
294643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2947303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
2948303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2949303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2950c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Don't use Smi-only elements optimizations for objects with the neander
2951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // map. There are too many cases where element values are set directly with a
2952c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // bottleneck to trap the Smi-only -> fast elements transition, and there
2953c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // appears to be no benefit for optimize this case.
2954c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Map* new_neander_map = Map::cast(obj);
2955830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  new_neander_map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND);
2956c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  set_neander_map(new_neander_map);
295743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2958ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_obj = AllocateJSObjectFromMap(neander_map());
2959303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
2960303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2961303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* elements;
2962303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_elements = AllocateFixedArray(2);
2963303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_elements->ToObject(&elements)) return false;
2964303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
296543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FixedArray::cast(elements)->set(0, Smi::FromInt(0));
296643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JSObject::cast(obj)->set_elements(FixedArray::cast(elements));
296768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_message_listeners(JSObject::cast(obj));
296843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
296943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
297043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
297143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29722abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
29732abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgvoid Heap::CreateJSEntryStub() {
29742abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  JSEntryStub stub;
29758432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  set_js_entry_code(*stub.GetCode(isolate()));
29762abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
29772abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
29782abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
29792abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgvoid Heap::CreateJSConstructEntryStub() {
29802abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  JSConstructEntryStub stub;
29818432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  set_js_construct_entry_code(*stub.GetCode(isolate()));
29822abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
29832abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
29842abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
298543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::CreateFixedStubs() {
298643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Here we create roots for fixed stubs. They are needed at GC
298743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for cooking and uncooking (check out frames.cc).
298843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The eliminates the need for doing dictionary lookup in the
298943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // stub cache for these stubs.
2990c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  HandleScope scope(isolate());
29912abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // gcc-4.4 has problem generating correct code of following snippet:
29924d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // {  JSEntryStub stub;
29934d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  //    js_entry_code_ = *stub.GetCode();
29942abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // }
29954d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // {  JSConstructEntryStub stub;
29964d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  //    js_construct_entry_code_ = *stub.GetCode();
29972abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // }
29982abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // To workaround the problem, make separate functions without inlining.
29992abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  Heap::CreateJSEntryStub();
30002abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  Heap::CreateJSConstructEntryStub();
3001c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3002c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Create stubs that should be there, so we don't unexpectedly have to
3003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // create them if we need them during the creation of another stub.
3004c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Stub creation mixes raw pointers and handles in an unsafe manner so
3005c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // we cannot create stubs while we are creating stubs.
30068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CodeStub::GenerateStubsAheadOfTime(isolate());
300743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
300843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
300943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
301043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::CreateInitialObjects() {
301143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* obj;
301243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
301343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The -0 value must be set before NumberFromDouble works.
3014303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateHeapNumber(-0.0, TENURED);
3015303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3016303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3017a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_minus_zero_value(HeapNumber::cast(obj));
301877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  ASSERT(std::signbit(minus_zero_value()->Number()) != 0);
301943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3020303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateHeapNumber(OS::nan_value(), TENURED);
3021303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3022303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3023a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_nan_value(HeapNumber::cast(obj));
302443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  { MaybeObject* maybe_obj = AllocateHeapNumber(V8_INFINITY, TENURED);
3026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!maybe_obj->ToObject(&obj)) return false;
3027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3028a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_infinity_value(HeapNumber::cast(obj));
302943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3030fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  // The hole has not been created yet, but we want to put something
30314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // predictable in the gaps in the string table, so lets make that Smi zero.
3032fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  set_the_hole_value(reinterpret_cast<Oddball*>(Smi::FromInt(0)));
3033fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
30344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate initial string table.
30356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  { MaybeObject* maybe_obj =
30366e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org        StringTable::Allocate(this, kInitialStringTableSize);
3037303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3038303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
30394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Don't use set_string_table() due to asserts.
30404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  roots_[kStringTableRootIndex] = obj;
304143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Finish initializing oddballs after creating the string table.
3043a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  { MaybeObject* maybe_obj =
3044a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org        undefined_value()->Initialize("undefined",
3045a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                                      nan_value(),
3046a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                                      Oddball::kUndefined);
3047a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3048303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
304943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3050a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // Initialize the null_value.
3051303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
3052a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org        null_value()->Initialize("null", Smi::FromInt(0), Oddball::kNull);
3053303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3054303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
305543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3056ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_obj = CreateOddball("true",
3057ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Smi::FromInt(1),
3058ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Oddball::kTrue);
3059303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3060303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3061a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_true_value(Oddball::cast(obj));
306243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3063ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_obj = CreateOddball("false",
3064ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Smi::FromInt(0),
3065ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Oddball::kFalse);
3066303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3067303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3068a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_false_value(Oddball::cast(obj));
306943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3070ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_obj = CreateOddball("hole",
3071ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Smi::FromInt(-1),
3072ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Oddball::kTheHole);
3073303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3074303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3075a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_the_hole_value(Oddball::cast(obj));
307643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30771fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  { MaybeObject* maybe_obj = CreateOddball("uninitialized",
30781fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                           Smi::FromInt(-1),
30791fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                           Oddball::kUninitialized);
30801fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
30811fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
30821fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_uninitialized_value(Oddball::cast(obj));
30831fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
3084d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  { MaybeObject* maybe_obj = CreateOddball("arguments_marker",
30852c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org                                           Smi::FromInt(-4),
3086ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Oddball::kArgumentMarker);
3087d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3088d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  }
3089a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_arguments_marker(Oddball::cast(obj));
3090d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
3091ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_obj = CreateOddball("no_interceptor_result_sentinel",
30922c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org                                           Smi::FromInt(-2),
3093ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Oddball::kOther);
3094303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3095303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
30960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  set_no_interceptor_result_sentinel(obj);
30970b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
3098ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_obj = CreateOddball("termination_exception",
30992c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org                                           Smi::FromInt(-3),
3100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Oddball::kOther);
3101303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3102303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3103c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  set_termination_exception(obj);
31040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
31054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  for (unsigned i = 0; i < ARRAY_SIZE(constant_string_table); i++) {
3106303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    { MaybeObject* maybe_obj =
31074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          InternalizeUtf8String(constant_string_table[i].contents);
3108303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_obj->ToObject(&obj)) return false;
3109303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
31104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    roots_[constant_string_table[i].index] = String::cast(obj);
311168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  }
311243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate the hidden string which is used to identify the hidden properties
31143b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  // in JSObjects. The hash code has a special value so that it will not match
31153b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  // the empty string when searching for the property. It cannot be part of the
311668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // loop above because it needs to be allocated manually with the special
31174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // hash code in place. The hash code for the hidden_string is zero to ensure
31183b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  // that it will always be at the first entry in property descriptors.
31194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  { MaybeObject* maybe_obj = AllocateOneByteInternalizedString(
31204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      OneByteVector("", 0), String::kEmptyStringHash);
3121303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3122303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
31234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  hidden_string_ = String::cast(obj);
31243b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org
31250b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Allocate the code_stubs dictionary. The initial size is set to avoid
31260b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // expanding the dictionary during bootstrapping.
31276e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  { MaybeObject* maybe_obj = UnseededNumberDictionary::Allocate(this, 128);
3128303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3129303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3130f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  set_code_stubs(UnseededNumberDictionary::cast(obj));
313143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
313264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
31330b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Allocate the non_monomorphic_cache used in stub-cache.cc. The initial size
31340b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // is set to avoid expanding the dictionary during bootstrapping.
31356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  { MaybeObject* maybe_obj = UnseededNumberDictionary::Allocate(this, 64);
3136303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3137303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3138f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  set_non_monomorphic_cache(UnseededNumberDictionary::cast(obj));
313943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3140e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  { MaybeObject* maybe_obj = AllocatePolymorphicCodeCache();
3141e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3142e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
3143e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  set_polymorphic_code_cache(PolymorphicCodeCache::cast(obj));
3144e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
3145720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  set_instanceof_cache_function(Smi::FromInt(0));
3146720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  set_instanceof_cache_map(Smi::FromInt(0));
3147720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  set_instanceof_cache_answer(Smi::FromInt(0));
3148720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
314943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CreateFixedStubs();
315043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3151d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // Allocate the dictionary of intrinsic function names.
31526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  { MaybeObject* maybe_obj =
31536e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org        NameDictionary::Allocate(this, Runtime::kNumFunctions);
3154303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3155303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3156ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this,
3157ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                                       obj);
3158303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3159303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3160750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  set_intrinsic_function_names(NameDictionary::cast(obj));
3161d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
3162fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  { MaybeObject* maybe_obj = AllocateInitialNumberStringCache();
3163fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3164fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
3165fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  set_number_string_cache(FixedArray::cast(obj));
316643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
316759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // Allocate cache for single character one byte strings.
3168303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
316959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        AllocateFixedArray(String::kMaxOneByteCharCode + 1, TENURED);
3170303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3171303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
317268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_single_character_string_cache(FixedArray::cast(obj));
317343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3174486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  // Allocate cache for string split.
317578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  { MaybeObject* maybe_obj = AllocateFixedArray(
317678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      RegExpResultsCache::kRegExpResultsCacheSize, TENURED);
3177486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3178486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
3179486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  set_string_split_cache(FixedArray::cast(obj));
3180486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
318178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  { MaybeObject* maybe_obj = AllocateFixedArray(
318278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      RegExpResultsCache::kRegExpResultsCacheSize, TENURED);
318378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
318478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
318578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  set_regexp_multiple_cache(FixedArray::cast(obj));
318678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
318743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate cache for external strings pointing to native source code.
3188303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateFixedArray(Natives::GetBuiltinsCount());
3189303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3190303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
319168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_natives_source_cache(FixedArray::cast(obj));
319243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3193e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Allocate object to hold object observation state.
3194e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
3195e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3196e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
3197e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  { MaybeObject* maybe_obj = AllocateJSObjectFromMap(Map::cast(obj));
3198e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3199e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
3200e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  set_observation_state(JSObject::cast(obj));
3201e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3202a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  { MaybeObject* maybe_obj = AllocateSymbol();
3203a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3204a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
3205a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  set_frozen_symbol(Symbol::cast(obj));
3206a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
3207d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  { MaybeObject* maybe_obj = AllocateSymbol();
3208d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3209d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
3210d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  set_elements_transition_symbol(Symbol::cast(obj));
3211d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
3212a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  { MaybeObject* maybe_obj = SeededNumberDictionary::Allocate(this, 0, TENURED);
3213a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3214a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
3215a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  SeededNumberDictionary::cast(obj)->set_requires_slow_elements();
3216a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  set_empty_slow_element_dictionary(SeededNumberDictionary::cast(obj));
3217a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
3218169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  { MaybeObject* maybe_obj = AllocateSymbol();
3219169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (!maybe_obj->ToObject(&obj)) return false;
3220169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
3221169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  set_observed_symbol(Symbol::cast(obj));
3222169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
3223d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // Handling of script id generation is in Factory::NewScript.
32241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  set_last_script_id(Smi::FromInt(v8::Script::kNoScriptId));
32257be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
32265a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Initialize keyed lookup cache.
3227ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->keyed_lookup_cache()->Clear();
32285aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
32295aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Initialize context slot cache.
3230ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->context_slot_cache()->Clear();
32315aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
32325aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Initialize descriptor cache.
3233ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->descriptor_lookup_cache()->Clear();
32345a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
3235b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  // Initialize compilation cache.
3236ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->compilation_cache()->Clear();
32379258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
323843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
323943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
324043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
324143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3242e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgbool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
3243e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  RootListIndex writable_roots[] = {
3244e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kStoreBufferTopRootIndex,
3245e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kStackLimitRootIndex,
32464121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org    kNumberStringCacheRootIndex,
3247e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kInstanceofCacheFunctionRootIndex,
3248e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kInstanceofCacheMapRootIndex,
3249e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kInstanceofCacheAnswerRootIndex,
3250e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kCodeStubsRootIndex,
3251e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kNonMonomorphicCacheRootIndex,
3252e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kPolymorphicCodeCacheRootIndex,
3253e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kLastScriptIdRootIndex,
3254e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kEmptyScriptRootIndex,
3255e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kRealStackLimitRootIndex,
3256e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kArgumentsAdaptorDeoptPCOffsetRootIndex,
3257e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kConstructStubDeoptPCOffsetRootIndex,
3258e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kGetterStubDeoptPCOffsetRootIndex,
3259e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    kSetterStubDeoptPCOffsetRootIndex,
32604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    kStringTableRootIndex,
3261e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  };
3262e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3263e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  for (unsigned int i = 0; i < ARRAY_SIZE(writable_roots); i++) {
3264e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (root_index == writable_roots[i])
3265e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      return true;
3266e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
3267e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return false;
3268e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
3269e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3270e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3271594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgbool Heap::RootCanBeTreatedAsConstant(RootListIndex root_index) {
3272594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return !RootCanBeWrittenAfterInitialization(root_index) &&
3273594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      !InNewSpace(roots_array_start()[root_index]);
3274594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
3275594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
3276594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
327778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgObject* RegExpResultsCache::Lookup(Heap* heap,
327878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                   String* key_string,
327978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                   Object* key_pattern,
328078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                   ResultsCacheType type) {
328178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  FixedArray* cache;
32824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!key_string->IsInternalizedString()) return Smi::FromInt(0);
328378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (type == STRING_SPLIT_SUBSTRINGS) {
328478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    ASSERT(key_pattern->IsString());
32854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0);
328678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    cache = heap->string_split_cache();
328778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  } else {
328878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    ASSERT(type == REGEXP_MULTIPLE_INDICES);
328978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    ASSERT(key_pattern->IsFixedArray());
329078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    cache = heap->regexp_multiple_cache();
329178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
329278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
329378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  uint32_t hash = key_string->Hash();
329478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
3295486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      ~(kArrayEntriesPerCacheEntry - 1));
329678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (cache->get(index + kStringOffset) == key_string &&
329778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->get(index + kPatternOffset) == key_pattern) {
3298486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    return cache->get(index + kArrayOffset);
3299486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
330078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  index =
330178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
330278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (cache->get(index + kStringOffset) == key_string &&
330378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->get(index + kPatternOffset) == key_pattern) {
3304486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    return cache->get(index + kArrayOffset);
3305486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
3306486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  return Smi::FromInt(0);
3307486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org}
3308486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
3309486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
331078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid RegExpResultsCache::Enter(Heap* heap,
331178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                               String* key_string,
331278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                               Object* key_pattern,
331378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                               FixedArray* value_array,
331478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                               ResultsCacheType type) {
331578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  FixedArray* cache;
33164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!key_string->IsInternalizedString()) return;
331778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (type == STRING_SPLIT_SUBSTRINGS) {
331878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    ASSERT(key_pattern->IsString());
33194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (!key_pattern->IsInternalizedString()) return;
332078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    cache = heap->string_split_cache();
332178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  } else {
332278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    ASSERT(type == REGEXP_MULTIPLE_INDICES);
332378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    ASSERT(key_pattern->IsFixedArray());
332478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    cache = heap->regexp_multiple_cache();
332578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
332678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
332778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  uint32_t hash = key_string->Hash();
332878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
3329486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      ~(kArrayEntriesPerCacheEntry - 1));
3330486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (cache->get(index + kStringOffset) == Smi::FromInt(0)) {
333178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    cache->set(index + kStringOffset, key_string);
333278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    cache->set(index + kPatternOffset, key_pattern);
333378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    cache->set(index + kArrayOffset, value_array);
333455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  } else {
333555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    uint32_t index2 =
333678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
333755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) {
333878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->set(index2 + kStringOffset, key_string);
333978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->set(index2 + kPatternOffset, key_pattern);
334078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->set(index2 + kArrayOffset, value_array);
334155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    } else {
334255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      cache->set(index2 + kStringOffset, Smi::FromInt(0));
334355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      cache->set(index2 + kPatternOffset, Smi::FromInt(0));
334455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      cache->set(index2 + kArrayOffset, Smi::FromInt(0));
334578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->set(index + kStringOffset, key_string);
334678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->set(index + kPatternOffset, key_pattern);
334778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->set(index + kArrayOffset, value_array);
334855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
3349486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
335078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // If the array is a reasonably short list of substrings, convert it into a
33514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // list of internalized strings.
335278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) {
335378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    for (int i = 0; i < value_array->length(); i++) {
335478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      String* str = String::cast(value_array->get(i));
33554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      Object* internalized_str;
33564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      MaybeObject* maybe_string = heap->InternalizeString(str);
33574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (maybe_string->ToObject(&internalized_str)) {
33584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        value_array->set(i, internalized_str);
3359486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      }
3360486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    }
3361486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
336278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // Convert backing store to a copy-on-write array.
336378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  value_array->set_map_no_write_barrier(heap->fixed_cow_array_map());
3364486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org}
3365486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
3366486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
336778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid RegExpResultsCache::Clear(FixedArray* cache) {
336878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  for (int i = 0; i < kRegExpResultsCacheSize; i++) {
3369486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    cache->set(i, Smi::FromInt(0));
3370486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
3371486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org}
3372486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
3373486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
3374fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgMaybeObject* Heap::AllocateInitialNumberStringCache() {
3375303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* maybe_obj =
3376fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      AllocateFixedArray(kInitialNumberStringCacheSize * 2, TENURED);
3377303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  return maybe_obj;
33780c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
33790c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
33800c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3381fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgint Heap::FullSizeNumberStringCacheLength() {
3382fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Compute the size of the number string cache based on the max newspace size.
3383fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // The number string cache has a minimum size based on twice the initial cache
3384fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // size to ensure that it is bigger after being made 'full size'.
3385fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  int number_string_cache_size = max_semispace_size_ / 512;
3386fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  number_string_cache_size = Max(kInitialNumberStringCacheSize * 2,
3387fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                                 Min(0x4000, number_string_cache_size));
3388fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // There is a string and a number per entry so the length is twice the number
3389fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // of entries.
3390fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  return number_string_cache_size * 2;
3391fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
3392fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
3393fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
3394fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgvoid Heap::AllocateFullSizeNumberStringCache() {
3395fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // The idea is to have a small number string cache in the snapshot to keep
3396fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // boot-time memory usage down.  If we expand the number string cache already
3397fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // while creating the snapshot then that didn't work out.
33985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  ASSERT(!Serializer::enabled() || FLAG_extra_code != NULL);
3399fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  MaybeObject* maybe_obj =
3400fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      AllocateFixedArray(FullSizeNumberStringCacheLength(), TENURED);
3401fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Object* new_cache;
3402fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (maybe_obj->ToObject(&new_cache)) {
3403fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    // We don't bother to repopulate the cache with entries from the old cache.
3404fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    // It will be repopulated soon enough with new strings.
3405fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    set_number_string_cache(FixedArray::cast(new_cache));
3406fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
3407fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // If allocation fails then we just return without doing anything.  It is only
3408fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // a cache, so best effort is OK here.
3409fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
3410fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
3411fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
34120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid Heap::FlushNumberStringCache() {
34130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Flush the number to string cache.
34140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  int len = number_string_cache()->length();
34150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  for (int i = 0; i < len; i++) {
3416ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    number_string_cache()->set_undefined(this, i);
34170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
34180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
34190c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
34200c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
342143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic inline int double_get_hash(double d) {
342243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DoubleRepresentation rep(d);
34230c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  return static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32);
342443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
342543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
342643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
342743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic inline int smi_get_hash(Smi* smi) {
34280c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  return smi->value();
342943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
343043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
343143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
343243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenObject* Heap::GetNumberStringCache(Object* number) {
343343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int hash;
34340c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  int mask = (number_string_cache()->length() >> 1) - 1;
343543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (number->IsSmi()) {
34360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    hash = smi_get_hash(Smi::cast(number)) & mask;
343743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
34380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    hash = double_get_hash(number->Number()) & mask;
343943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
344068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  Object* key = number_string_cache()->get(hash * 2);
344143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (key == number) {
344268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    return String::cast(number_string_cache()->get(hash * 2 + 1));
344343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (key->IsHeapNumber() &&
344443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             number->IsHeapNumber() &&
344543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             key->Number() == number->Number()) {
344668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    return String::cast(number_string_cache()->get(hash * 2 + 1));
344743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
344843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return undefined_value();
344943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
345043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
345143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
345243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::SetNumberStringCache(Object* number, String* string) {
345343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int hash;
34540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  int mask = (number_string_cache()->length() >> 1) - 1;
345543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (number->IsSmi()) {
34560c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    hash = smi_get_hash(Smi::cast(number)) & mask;
345743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
34580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    hash = double_get_hash(number->Number()) & mask;
345943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3460fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (number_string_cache()->get(hash * 2) != undefined_value() &&
3461fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      number_string_cache()->length() != FullSizeNumberStringCacheLength()) {
3462fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    // The first time we have a hash collision, we move to the full sized
3463fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    // number string cache.
3464fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    AllocateFullSizeNumberStringCache();
3465fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    return;
3466fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
3467fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  number_string_cache()->set(hash * 2, number);
346868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  number_string_cache()->set(hash * 2 + 1, string);
346943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
347043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
347143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3472303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::NumberToString(Object* number,
347357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                                  bool check_number_string_cache,
347457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                                  PretenureFlag pretenure) {
3475ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->counters()->number_to_string_runtime()->Increment();
3476357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  if (check_number_string_cache) {
3477357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org    Object* cached = GetNumberStringCache(number);
3478357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org    if (cached != undefined_value()) {
3479357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org      return cached;
3480357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org    }
3481c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
3482c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
3483c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  char arr[100];
3484c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  Vector<char> buffer(arr, ARRAY_SIZE(arr));
3485c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  const char* str;
3486c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  if (number->IsSmi()) {
3487c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    int num = Smi::cast(number)->value();
3488c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    str = IntToCString(num, buffer);
3489c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  } else {
3490c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    double num = HeapNumber::cast(number)->value();
3491c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    str = DoubleToCString(num, buffer);
3492c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
3493c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
3494303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* js_string;
349557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  MaybeObject* maybe_js_string =
349657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      AllocateStringFromOneByte(CStrVector(str), pretenure);
3497303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  if (maybe_js_string->ToObject(&js_string)) {
3498303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    SetNumberStringCache(number, String::cast(js_string));
3499c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
3500303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  return maybe_js_string;
3501c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
3502c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
3503c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
3504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comMaybeObject* Heap::Uint32ToString(uint32_t value,
3505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  bool check_number_string_cache) {
3506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Object* number;
3507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MaybeObject* maybe = NumberFromUint32(value);
3508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!maybe->To<Object>(&number)) return maybe;
3509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return NumberToString(number, check_number_string_cache);
3510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
35133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgMap* Heap::MapForExternalArrayType(ExternalArrayType array_type) {
35143811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  return Map::cast(roots_[RootIndexForExternalArrayType(array_type)]);
35153811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
35163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
35173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
35183811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgHeap::RootListIndex Heap::RootIndexForExternalArrayType(
35193811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    ExternalArrayType array_type) {
35203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  switch (array_type) {
35213811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    case kExternalByteArray:
35223811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      return kExternalByteArrayMapRootIndex;
35233811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    case kExternalUnsignedByteArray:
35243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      return kExternalUnsignedByteArrayMapRootIndex;
35253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    case kExternalShortArray:
35263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      return kExternalShortArrayMapRootIndex;
35273811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    case kExternalUnsignedShortArray:
35283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      return kExternalUnsignedShortArrayMapRootIndex;
35293811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    case kExternalIntArray:
35303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      return kExternalIntArrayMapRootIndex;
35313811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    case kExternalUnsignedIntArray:
35323811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      return kExternalUnsignedIntArrayMapRootIndex;
35333811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    case kExternalFloatArray:
35343811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      return kExternalFloatArrayMapRootIndex;
35353847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    case kExternalDoubleArray:
35363847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      return kExternalDoubleArrayMapRootIndex;
35374d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    case kExternalPixelArray:
35384d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      return kExternalPixelArrayMapRootIndex;
35393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    default:
35403811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      UNREACHABLE();
35413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      return kUndefinedValueRootIndex;
35423811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
35433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
35443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
35454e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgHeap::RootListIndex Heap::RootIndexForEmptyExternalArray(
35464e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    ElementsKind elementsKind) {
35474e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  switch (elementsKind) {
35484e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EXTERNAL_BYTE_ELEMENTS:
35494e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kEmptyExternalByteArrayRootIndex;
35504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
35514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kEmptyExternalUnsignedByteArrayRootIndex;
35524e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EXTERNAL_SHORT_ELEMENTS:
35534e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kEmptyExternalShortArrayRootIndex;
35544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
35554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kEmptyExternalUnsignedShortArrayRootIndex;
35564e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EXTERNAL_INT_ELEMENTS:
35574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kEmptyExternalIntArrayRootIndex;
35584e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
35594e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kEmptyExternalUnsignedIntArrayRootIndex;
35604e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EXTERNAL_FLOAT_ELEMENTS:
35614e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kEmptyExternalFloatArrayRootIndex;
35624e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EXTERNAL_DOUBLE_ELEMENTS:
35634e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kEmptyExternalDoubleArrayRootIndex;
35644e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    case EXTERNAL_PIXEL_ELEMENTS:
35654e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kEmptyExternalPixelArrayRootIndex;
35664e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    default:
35674e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      UNREACHABLE();
35684e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kUndefinedValueRootIndex;
35694e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
35704e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
35714e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
3572e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
35734e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgExternalArray* Heap::EmptyExternalArrayForMap(Map* map) {
35744e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  return ExternalArray::cast(
35754e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      roots_[RootIndexForEmptyExternalArray(map->elements_kind())]);
35764e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
35774e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
35784e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
35794e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
35803811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
3581303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::NumberFromDouble(double value, PretenureFlag pretenure) {
35824111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // We need to distinguish the minus zero value and this cannot be
35834111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // done after conversion to int. Doing this by comparing bit
35844111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // patterns is faster than using fpclassify() et al.
35854111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  static const DoubleRepresentation minus_zero(-0.0);
358643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35874111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  DoubleRepresentation rep(value);
35884111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  if (rep.bits == minus_zero.bits) {
35894111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    return AllocateHeapNumber(-0.0, pretenure);
35904111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
359143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35924111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  int int_value = FastD2I(value);
35934111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  if (value == int_value && Smi::IsValid(int_value)) {
35944111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    return Smi::FromInt(int_value);
35954111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
35964111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
35974111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // Materialize the value in the heap.
35984111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  return AllocateHeapNumber(value, pretenure);
359943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
360043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
360143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3602ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgMaybeObject* Heap::AllocateForeign(Address address, PretenureFlag pretenure) {
3603ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Statically ensure that it is safe to allocate foreigns in paged spaces.
3604ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  STATIC_ASSERT(Foreign::kSize <= Page::kMaxNonCodeHeapObjectSize);
36050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
3606c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Foreign* result;
3607c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  MaybeObject* maybe_result = Allocate(foreign_map(), space);
3608c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (!maybe_result->To(&result)) return maybe_result;
3609c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  result->set_foreign_address(address);
361043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
361143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
361243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
361343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3614303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
36157c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  SharedFunctionInfo* share;
36167c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  MaybeObject* maybe = Allocate(shared_function_info_map(), OLD_POINTER_SPACE);
36177c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  if (!maybe->To<SharedFunctionInfo>(&share)) return maybe;
361843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36197c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // Set pointer fields.
362043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  share->set_name(name);
36217979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
362243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  share->set_code(illegal);
3623906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  share->set_optimized_code_map(Smi::FromInt(0));
36248432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  share->set_scope_info(ScopeInfo::Empty(isolate_));
36257c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  Code* construct_stub =
36267c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      isolate_->builtins()->builtin(Builtins::kJSConstructStubGeneric);
36275aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  share->set_construct_stub(construct_stub);
36284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  share->set_instance_class_name(Object_string());
362927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  share->set_function_data(undefined_value(), SKIP_WRITE_BARRIER);
363027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  share->set_script(undefined_value(), SKIP_WRITE_BARRIER);
363127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  share->set_debug_info(undefined_value(), SKIP_WRITE_BARRIER);
363227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  share->set_inferred_name(empty_string(), SKIP_WRITE_BARRIER);
363327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  share->set_initial_map(undefined_value(), SKIP_WRITE_BARRIER);
3634b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  share->set_ast_node_count(0);
36357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  share->set_counters(0);
36367c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
36377c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // Set integer fields (smi or int, depending on the architecture).
36387c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  share->set_length(0);
36397c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  share->set_formal_parameter_count(0);
36407c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  share->set_expected_nof_properties(0);
364130ce411529579186181838984710b0b0980857aaricow@chromium.org  share->set_num_literals(0);
36427c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  share->set_start_position_and_type(0);
364330ce411529579186181838984710b0b0980857aaricow@chromium.org  share->set_end_position(0);
364430ce411529579186181838984710b0b0980857aaricow@chromium.org  share->set_function_token_position(0);
36457c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // All compiler hints default to false or 0.
36467c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  share->set_compiler_hints(0);
36477c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  share->set_opt_count(0);
36487c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
36497c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return share;
365043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
365143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
365243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
365331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.orgMaybeObject* Heap::AllocateJSMessageObject(String* type,
365431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org                                           JSArray* arguments,
365531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org                                           int start_position,
365631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org                                           int end_position,
365731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org                                           Object* script,
365831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org                                           Object* stack_trace,
365931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org                                           Object* stack_frames) {
366031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  Object* result;
366131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  { MaybeObject* maybe_result = Allocate(message_object_map(), NEW_SPACE);
366231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
366331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  }
366431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  JSMessageObject* message = JSMessageObject::cast(result);
366527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  message->set_properties(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER);
3666830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  message->initialize_elements();
366727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  message->set_elements(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER);
366831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  message->set_type(type);
366931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  message->set_arguments(arguments);
367031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  message->set_start_position(start_position);
367131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  message->set_end_position(end_position);
367231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  message->set_script(script);
367331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  message->set_stack_trace(stack_trace);
367431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  message->set_stack_frames(stack_frames);
367531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  return result;
367631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org}
367731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
367831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
367931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
36806141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org// Returns true for a character in a range.  Both limits are inclusive.
36816141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.orgstatic inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
36826141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // This makes uses of the the unsigned wraparound.
36836141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  return character - from <= to - from;
36846141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org}
36856141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
36866141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
3687303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMUST_USE_RESULT static inline MaybeObject* MakeOrFindTwoCharacterString(
3688ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Heap* heap,
3689a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint16_t c1,
3690a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint16_t c2) {
36914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  String* result;
36926141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // Numeric strings have a different hash algorithm not known by
36934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // LookupTwoCharsStringIfExists, so we skip this step for such strings.
36946141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  if ((!Between(c1, '0', '9') || !Between(c2, '0', '9')) &&
36954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      heap->string_table()->LookupTwoCharsStringIfExists(c1, c2, &result)) {
36964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return result;
36976141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // Now we know the length is 2, we might as well make use of that fact
36986141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // when building the new string.
369959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  } else if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
3700a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // We can do this.
370159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1));  // because of this.
3702303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* result;
37038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    { MaybeObject* maybe_result = heap->AllocateRawOneByteString(2);
3704303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_result->ToObject(&result)) return maybe_result;
3705303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
370659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
370759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    dest[0] = static_cast<uint8_t>(c1);
370859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    dest[1] = static_cast<uint8_t>(c2);
37096141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    return result;
37106141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  } else {
3711303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* result;
3712ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    { MaybeObject* maybe_result = heap->AllocateRawTwoByteString(2);
3713303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_result->ToObject(&result)) return maybe_result;
3714303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
37156141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    uc16* dest = SeqTwoByteString::cast(result)->GetChars();
37166141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    dest[0] = c1;
37176141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    dest[1] = c2;
37186141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    return result;
37196141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  }
37206141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org}
37216141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
37226141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
3723303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateConsString(String* first, String* second) {
3724bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int first_length = first->length();
3725c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  if (first_length == 0) {
3726c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    return second;
3727c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
37283e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
3729bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int second_length = second->length();
3730c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  if (second_length == 0) {
3731c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    return first;
3732c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
37333e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
37345a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  int length = first_length + second_length;
37356141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
37366141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // Optimization for 2-byte strings often used as keys in a decompression
37374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // dictionary.  Check whether we already have the string in the string
37386141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // table to prevent creation of many unneccesary strings.
37396141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  if (length == 2) {
3740a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint16_t c1 = first->Get(0);
3741a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint16_t c2 = second->Get(0);
3742ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return MakeOrFindTwoCharacterString(this, c1, c2);
37436141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  }
37446141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
374559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  bool first_is_one_byte = first->IsOneByteRepresentation();
374659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  bool second_is_one_byte = second->IsOneByteRepresentation();
374759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  bool is_one_byte = first_is_one_byte && second_is_one_byte;
37483e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // Make sure that an out of memory exception is thrown if the length
37499d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // of the new cons string is too large.
37509d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (length > String::kMaxLength || length < 0) {
3751ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate()->context()->mark_out_of_memory();
375259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0x4);
37533e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  }
37543e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
3755ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  bool is_one_byte_data_in_two_byte_string = false;
375659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (!is_one_byte) {
37575ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org    // At least one of the strings uses two-byte representation so we
37582efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // can't use the fast case code for short ASCII strings below, but
37592efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // we can try to save memory if all chars actually fit in ASCII.
3760ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    is_one_byte_data_in_two_byte_string =
3761ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        first->HasOnlyOneByteChars() && second->HasOnlyOneByteChars();
3762ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if (is_one_byte_data_in_two_byte_string) {
3763ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment();
37645ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org    }
37655ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  }
37665ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
376743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the resulting string is small make a flat string.
37682efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  if (length < ConsString::kMinLength) {
37694668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    // Note that neither of the two inputs can be a slice because:
37702efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength);
3771bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(first->IsFlat());
3772bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(second->IsFlat());
377359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    if (is_one_byte) {
3774303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      Object* result;
37758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      { MaybeObject* maybe_result = AllocateRawOneByteString(length);
3776303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        if (!maybe_result->ToObject(&result)) return maybe_result;
3777303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
37785a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      // Copy the characters into the new object.
377959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
37803e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org      // Copy first part.
378159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      const uint8_t* src;
3782ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org      if (first->IsExternalString()) {
37830ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry        src = ExternalAsciiString::cast(first)->GetChars();
3784ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org      } else {
3785fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        src = SeqOneByteString::cast(first)->GetChars();
3786ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org      }
37873e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org      for (int i = 0; i < first_length; i++) *dest++ = src[i];
37883e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org      // Copy second part.
3789ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org      if (second->IsExternalString()) {
37900ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry        src = ExternalAsciiString::cast(second)->GetChars();
3791ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org      } else {
3792fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        src = SeqOneByteString::cast(second)->GetChars();
3793ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org      }
37943e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org      for (int i = 0; i < second_length; i++) *dest++ = src[i];
37955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      return result;
37965a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    } else {
3797ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      if (is_one_byte_data_in_two_byte_string) {
3798303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        Object* result;
37998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        { MaybeObject* maybe_result = AllocateRawOneByteString(length);
3800303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org          if (!maybe_result->ToObject(&result)) return maybe_result;
3801303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        }
3802aa1b6165f7efc4a40c71aa4cb22966c480108fa5ricow@chromium.org        // Copy the characters into the new object.
380359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
3804aa1b6165f7efc4a40c71aa4cb22966c480108fa5ricow@chromium.org        String::WriteToFlat(first, dest, 0, first_length);
3805aa1b6165f7efc4a40c71aa4cb22966c480108fa5ricow@chromium.org        String::WriteToFlat(second, dest + first_length, 0, second_length);
3806ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment();
3807aa1b6165f7efc4a40c71aa4cb22966c480108fa5ricow@chromium.org        return result;
3808aa1b6165f7efc4a40c71aa4cb22966c480108fa5ricow@chromium.org      }
3809aa1b6165f7efc4a40c71aa4cb22966c480108fa5ricow@chromium.org
3810303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      Object* result;
3811303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      { MaybeObject* maybe_result = AllocateRawTwoByteString(length);
3812303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        if (!maybe_result->ToObject(&result)) return maybe_result;
3813303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
38145a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      // Copy the characters into the new object.
38155a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      uc16* dest = SeqTwoByteString::cast(result)->GetChars();
3816bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      String::WriteToFlat(first, dest, 0, first_length);
3817bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      String::WriteToFlat(second, dest + first_length, 0, second_length);
38185a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      return result;
381943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
382043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
382143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3822ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Map* map = (is_one_byte || is_one_byte_data_in_two_byte_string) ?
38235ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org      cons_ascii_string_map() : cons_string_map();
382443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3825303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
3826303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
3827303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
3828303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3829b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
383079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
383143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ConsString* cons_string = ConsString::cast(result);
3832b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc);
3833ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  cons_string->set_length(length);
3834ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  cons_string->set_hash_field(String::kEmptyHashField);
3835c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  cons_string->set_first(first, mode);
3836c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  cons_string->set_second(second, mode);
383743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
383843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
383943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
384043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3841303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateSubString(String* buffer,
384204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                     int start,
384304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                     int end,
384404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                     PretenureFlag pretenure) {
384543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int length = end - start;
38462efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  if (length <= 0) {
384704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    return empty_string();
384804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  } else if (length == 1) {
3849ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return LookupSingleCharacterStringFromCode(buffer->Get(start));
38506141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  } else if (length == 2) {
38516141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    // Optimization for 2-byte strings often used as keys in a decompression
38524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // dictionary.  Check whether we already have the string in the string
38534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // table to prevent creation of many unnecessary strings.
3854a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint16_t c1 = buffer->Get(start);
3855a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint16_t c2 = buffer->Get(start + 1);
3856ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return MakeOrFindTwoCharacterString(this, c1, c2);
38577c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
38587c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
385943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make an attempt to flatten the buffer to reduce access time.
38609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  buffer = buffer->TryFlattenGetString();
386143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38624668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  if (!FLAG_string_slices ||
3863c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !buffer->IsFlat() ||
38644668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      length < SlicedString::kMinLength ||
38654668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      pretenure == TENURED) {
38664668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    Object* result;
3867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // WriteToFlat takes care of the case when an indirect string has a
3868c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // different encoding from its underlying string.  These encodings may
3869c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // differ because of externalization.
387059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    bool is_one_byte = buffer->IsOneByteRepresentation();
387159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    { MaybeObject* maybe_result = is_one_byte
38728e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                  ? AllocateRawOneByteString(length, pretenure)
3873c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  : AllocateRawTwoByteString(length, pretenure);
38744668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      if (!maybe_result->ToObject(&result)) return maybe_result;
38754668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    }
38764668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    String* string_result = String::cast(result);
38774668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    // Copy the characters into the new object.
387859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    if (is_one_byte) {
38798e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      ASSERT(string_result->IsOneByteRepresentation());
388059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      uint8_t* dest = SeqOneByteString::cast(string_result)->GetChars();
38814668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      String::WriteToFlat(buffer, dest, start, end);
38824668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    } else {
38834668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      ASSERT(string_result->IsTwoByteRepresentation());
38844668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      uc16* dest = SeqTwoByteString::cast(string_result)->GetChars();
38854668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      String::WriteToFlat(buffer, dest, start, end);
38864668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    }
38874668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    return result;
38884668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  }
38894668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org
38904668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  ASSERT(buffer->IsFlat());
3891c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#if VERIFY_HEAP
3892394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
3893394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    buffer->StringVerify();
3894394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
38954668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org#endif
38964668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org
3897303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
3898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // When slicing an indirect string we use its encoding for a newly created
3899c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // slice and don't check the encoding of the underlying string.  This is safe
3900c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // even if the encodings are different because of externalization.  If an
3901c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // indirect ASCII string is pointing to a two-byte string, the two-byte char
3902c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // codes of the underlying string must still fit into ASCII (because
3903c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // externalization must not change char codes).
39048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  { Map* map = buffer->IsOneByteRepresentation()
39054668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org                 ? sliced_ascii_string_map()
39064668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org                 : sliced_string_map();
39074668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
3908303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
3909303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
39104668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org
391179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
39124668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  SlicedString* sliced_string = SlicedString::cast(result);
39134668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  sliced_string->set_length(length);
39144668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  sliced_string->set_hash_field(String::kEmptyHashField);
39154668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  if (buffer->IsConsString()) {
39164668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    ConsString* cons = ConsString::cast(buffer);
39174668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    ASSERT(cons->second()->length() == 0);
39184668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    sliced_string->set_parent(cons->first());
39194668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    sliced_string->set_offset(start);
39204668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  } else if (buffer->IsSlicedString()) {
39214668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    // Prevent nesting sliced strings.
39224668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    SlicedString* parent_slice = SlicedString::cast(buffer);
39234668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    sliced_string->set_parent(parent_slice->parent());
39244668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    sliced_string->set_offset(start + parent_slice->offset());
3925c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  } else {
39264668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    sliced_string->set_parent(buffer);
39274668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    sliced_string->set_offset(start);
392843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(sliced_string->parent()->IsSeqString() ||
3930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         sliced_string->parent()->IsExternalString());
393143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
393243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
393343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
393443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3935303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateExternalStringFromAscii(
3936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    const ExternalAsciiString::Resource* resource) {
3937c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  size_t length = resource->length();
3938ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  if (length > static_cast<size_t>(String::kMaxLength)) {
3939ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate()->context()->mark_out_of_memory();
394059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0x5);
394143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
394243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3943ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  Map* map = external_ascii_string_map();
3944303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
3945303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
3946303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
3947303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
394843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
394943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ExternalAsciiString* external_string = ExternalAsciiString::cast(result);
3950c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  external_string->set_length(static_cast<int>(length));
3951ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  external_string->set_hash_field(String::kEmptyHashField);
395243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  external_string->set_resource(resource);
395343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
395443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
395543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
395643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
395743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3958303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateExternalStringFromTwoByte(
3959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    const ExternalTwoByteString::Resource* resource) {
3960c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  size_t length = resource->length();
3961c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  if (length > static_cast<size_t>(String::kMaxLength)) {
3962ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate()->context()->mark_out_of_memory();
396359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0x6);
3964c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
3965ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
39665ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // For small strings we check whether the resource contains only
396759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // one byte characters.  If yes, we use a different string map.
3968ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  static const size_t kOneByteCheckLengthLimit = 32;
3969ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  bool is_one_byte = length <= kOneByteCheckLengthLimit &&
397059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      String::IsOneByte(resource->data(), static_cast<int>(length));
397159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  Map* map = is_one_byte ?
3972ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      external_string_with_one_byte_data_map() : external_string_map();
3973303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
3974303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
3975303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
3976303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
397743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
397843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result);
3979c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  external_string->set_length(static_cast<int>(length));
3980ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  external_string->set_hash_field(String::kEmptyHashField);
398143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  external_string->set_resource(resource);
398243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
398343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
398443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
398543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
398643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3987303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) {
398859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (code <= String::kMaxOneByteCharCode) {
3989ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Object* value = single_character_string_cache()->get(code);
3990ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (value != undefined_value()) return value;
39915a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
399259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    uint8_t buffer[1];
399359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    buffer[0] = static_cast<uint8_t>(code);
3994303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* result;
3995a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    MaybeObject* maybe_result =
39964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        InternalizeOneByteString(Vector<const uint8_t>(buffer, 1));
39975a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
3998303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
3999ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    single_character_string_cache()->set(code, result);
400043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return result;
400143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
40025a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
4003303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
4004ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_result = AllocateRawTwoByteString(1);
4005303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
4006303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
4007870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  String* answer = String::cast(result);
4008bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  answer->Set(0, code);
4009870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  return answer;
401043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
401143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
401243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4013303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateByteArray(int length, PretenureFlag pretenure) {
40140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  if (length < 0 || length > ByteArray::kMaxLength) {
401559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0x7);
40160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
4017a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (pretenure == NOT_TENURED) {
4018a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return AllocateByteArray(length);
4019a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
4020a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int size = ByteArray::SizeFor(length);
402121af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  AllocationSpace space =
402221af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org      (size > Page::kMaxNonCodeHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE;
4023303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
402421af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  { MaybeObject* maybe_result = AllocateRaw(size, space, space);
4025303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
4026303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
4027a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
402864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  reinterpret_cast<ByteArray*>(result)->set_map_no_write_barrier(
402964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      byte_array_map());
403030ce411529579186181838984710b0b0980857aaricow@chromium.org  reinterpret_cast<ByteArray*>(result)->set_length(length);
4031a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return result;
4032a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
4033a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
4034a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
4035303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateByteArray(int length) {
40360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  if (length < 0 || length > ByteArray::kMaxLength) {
403759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0x8);
40380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
403943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int size = ByteArray::SizeFor(length);
40409258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  AllocationSpace space =
4041ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      (size > Page::kMaxNonCodeHeapObjectSize) ? LO_SPACE : NEW_SPACE;
4042303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
4043303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
4044303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
4045303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
404643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
404764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  reinterpret_cast<ByteArray*>(result)->set_map_no_write_barrier(
404864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      byte_array_map());
404930ce411529579186181838984710b0b0980857aaricow@chromium.org  reinterpret_cast<ByteArray*>(result)->set_length(length);
405043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
405143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
405243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
405343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40546f10e41fef1524c70846d970268de222e41c594cager@chromium.orgvoid Heap::CreateFillerObjectAt(Address addr, int size) {
40556f10e41fef1524c70846d970268de222e41c594cager@chromium.org  if (size == 0) return;
40566f10e41fef1524c70846d970268de222e41c594cager@chromium.org  HeapObject* filler = HeapObject::FromAddress(addr);
40576f10e41fef1524c70846d970268de222e41c594cager@chromium.org  if (size == kPointerSize) {
405864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    filler->set_map_no_write_barrier(one_pointer_filler_map());
4059013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  } else if (size == 2 * kPointerSize) {
406064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    filler->set_map_no_write_barrier(two_pointer_filler_map());
40616f10e41fef1524c70846d970268de222e41c594cager@chromium.org  } else {
406264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    filler->set_map_no_write_barrier(free_space_map());
4063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FreeSpace::cast(filler)->set_size(size);
40646f10e41fef1524c70846d970268de222e41c594cager@chromium.org  }
40656f10e41fef1524c70846d970268de222e41c594cager@chromium.org}
40666f10e41fef1524c70846d970268de222e41c594cager@chromium.org
40676f10e41fef1524c70846d970268de222e41c594cager@chromium.org
4068303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateExternalArray(int length,
4069303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         ExternalArrayType array_type,
4070303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         void* external_pointer,
4071303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         PretenureFlag pretenure) {
40723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
4073303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
4074303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = AllocateRaw(ExternalArray::kAlignedSize,
4075303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                            space,
4076303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                            OLD_DATA_SPACE);
4077303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
4078303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
40793811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
408064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  reinterpret_cast<ExternalArray*>(result)->set_map_no_write_barrier(
40813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      MapForExternalArrayType(array_type));
40823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  reinterpret_cast<ExternalArray*>(result)->set_length(length);
40833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  reinterpret_cast<ExternalArray*>(result)->set_external_pointer(
40843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      external_pointer);
40853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
40863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  return result;
40873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
40883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
40893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
4090303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::CreateCode(const CodeDesc& desc,
4091303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                              Code::Flags flags,
40924d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org                              Handle<Object> self_reference,
4093b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                              bool immovable,
4094b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                              bool crankshafted) {
40954a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  // Allocate ByteArray before the Code object, so that we do not risk
40964a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  // leaving uninitialized Code object (and breaking the heap).
409704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  ByteArray* reloc_info;
409804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  MaybeObject* maybe_reloc_info = AllocateByteArray(desc.reloc_size, TENURED);
409904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  if (!maybe_reloc_info->To(&reloc_info)) return maybe_reloc_info;
41004a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
41014d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Compute size.
41024a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int body_size = RoundUp(desc.instr_size, kObjectAlignment);
41036a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  int obj_size = Code::SizeFor(body_size);
41044a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment));
4105303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* maybe_result;
41064d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Large code objects and code objects which should stay at a fixed address
41074d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // are allocated in large object space.
410856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  HeapObject* result;
410956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  bool force_lo_space = obj_size > code_space()->AreaSize();
411056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  if (force_lo_space) {
4111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE);
41129258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  } else {
4113303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    maybe_result = code_space_->AllocateRaw(obj_size);
41149258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
411556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  if (!maybe_result->To<HeapObject>(&result)) return maybe_result;
411643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
411756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  if (immovable && !force_lo_space &&
411856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      // Objects on the first page of each space are never moved.
411956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      !code_space_->FirstPage()->Contains(result->address())) {
412056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    // Discard the first code allocation, which was on a page where it could be
412156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    // moved.
412256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    CreateFillerObjectAt(result->address(), obj_size);
412356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE);
412456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    if (!maybe_result->To<HeapObject>(&result)) return maybe_result;
412556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  }
412643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
412743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize the object
412856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  result->set_map_no_write_barrier(code_map());
412943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Code* code = Code::cast(result);
4130ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(!isolate_->code_range()->exists() ||
4131ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate_->code_range()->contains(code->address()));
413243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  code->set_instruction_size(desc.instr_size);
413304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  code->set_relocation_info(reloc_info);
413443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  code->set_flags(flags);
4135c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  if (code->is_call_stub() || code->is_keyed_call_stub()) {
4136c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    code->set_check_type(RECEIVER_MAP_CHECK);
4137c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
4138b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  code->set_is_crankshafted(crankshafted);
413927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER);
4140fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  code->InitializeTypeFeedbackInfoNoWriteBarrier(undefined_value());
414127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER);
4142659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  code->set_gc_metadata(Smi::FromInt(0));
414388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  code->set_ic_age(global_ic_age_);
414483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  code->set_prologue_offset(kPrologueOffsetNotSet);
4145003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (code->kind() == Code::OPTIMIZED_FUNCTION) {
4146003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    code->set_marked_for_deoptimization(false);
4147003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
4148061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  // Allow self references to created code object by patching the handle to
4149061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  // point to the newly allocated Code object.
4150061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  if (!self_reference.is_null()) {
4151061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org    *(self_reference.location()) = code;
4152a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
4153a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // Migrate generated code.
4154a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // The generated code can contain Object** values (typically from handles)
4155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // that are dereferenced during the copy to point directly to the actual heap
4156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // objects. These pointers can include references to the code object itself,
4157a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // through the self_reference parameter.
4158a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  code->CopyFrom(desc);
415943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4160c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
4161394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
4162394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    code->Verify();
4163394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
416443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
416543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return code;
416643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
416743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
416843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4169303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::CopyCode(Code* code) {
417043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate an object the same size as the code object.
417143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int obj_size = code->Size();
4172303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* maybe_result;
4173ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  if (obj_size > code_space()->AreaSize()) {
4174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE);
41759258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  } else {
4176303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    maybe_result = code_space_->AllocateRaw(obj_size);
41779258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
41789258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
4179303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
4180303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  if (!maybe_result->ToObject(&result)) return maybe_result;
418143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
418243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Copy code object.
418343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address old_addr = code->address();
418443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address new_addr = reinterpret_cast<HeapObject*>(result)->address();
418530ce411529579186181838984710b0b0980857aaricow@chromium.org  CopyBlock(new_addr, old_addr, obj_size);
418643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Relocate the copy.
418743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Code* new_code = Code::cast(result);
4188ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(!isolate_->code_range()->exists() ||
4189ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate_->code_range()->contains(code->address()));
419043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  new_code->Relocate(new_addr - old_addr);
419143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return new_code;
419243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
419343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
419443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4195303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::CopyCode(Code* code, Vector<byte> reloc_info) {
41964a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  // Allocate ByteArray before the Code object, so that we do not risk
41974a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  // leaving uninitialized Code object (and breaking the heap).
4198303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* reloc_info_array;
4199303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_reloc_info_array =
4200303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateByteArray(reloc_info.length(), TENURED);
4201303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_reloc_info_array->ToObject(&reloc_info_array)) {
4202303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      return maybe_reloc_info_array;
4203303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
4204303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
42054a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
42064a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment);
4207086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
42086a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  int new_obj_size = Code::SizeFor(new_body_size);
4209086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4210086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  Address old_addr = code->address();
4211086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4212b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  size_t relocation_offset =
42134a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com      static_cast<size_t>(code->instruction_end() - old_addr);
4214086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4215303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* maybe_result;
4216ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  if (new_obj_size > code_space()->AreaSize()) {
4217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    maybe_result = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE);
4218086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  } else {
4219303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    maybe_result = code_space_->AllocateRaw(new_obj_size);
4220086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
4221086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4222303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
4223303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  if (!maybe_result->ToObject(&result)) return maybe_result;
4224086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4225086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Copy code object.
4226086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  Address new_addr = reinterpret_cast<HeapObject*>(result)->address();
4227086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4228086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Copy header and instructions.
4229f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CopyBytes(new_addr, old_addr, relocation_offset);
4230086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4231086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  Code* new_code = Code::cast(result);
42324a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  new_code->set_relocation_info(ByteArray::cast(reloc_info_array));
4233086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
42344a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  // Copy patched rinfo.
4235c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  CopyBytes(new_code->relocation_start(),
4236c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org            reloc_info.start(),
4237f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org            static_cast<size_t>(reloc_info.length()));
4238086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4239086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Relocate the copy.
4240ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(!isolate_->code_range()->exists() ||
4241ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate_->code_range()->contains(code->address()));
4242086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  new_code->Relocate(new_addr - old_addr);
4243086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4244c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
4245394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
4246394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    code->Verify();
4247394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
4248086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org#endif
4249086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  return new_code;
4250086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org}
4251086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
4252086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
42534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::AllocateWithAllocationSite(Map* map, AllocationSpace space,
4254bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<AllocationSite> allocation_site) {
42554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(gc_state_ == NOT_IN_GC);
42564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(map->instance_type() != MAP_TYPE);
42574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // If allocation failures are disallowed, we may allocate in a different
42584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // space when new space is full and the object is not a large object.
42594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  AllocationSpace retry_space =
42604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type());
4261ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  int size = map->instance_size() + AllocationMemento::kSize;
42624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* result;
42634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  MaybeObject* maybe_result = AllocateRaw(size, space, retry_space);
42644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!maybe_result->ToObject(&result)) return maybe_result;
42654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // No need for write barrier since object is white and map is in old space.
42664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(map);
4267ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
42684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      reinterpret_cast<Address>(result) + map->instance_size());
4269ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  alloc_memento->set_map_no_write_barrier(allocation_memento_map());
4270ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  alloc_memento->set_allocation_site(*allocation_site, SKIP_WRITE_BARRIER);
42714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return result;
42724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
42734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
42744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4275303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::Allocate(Map* map, AllocationSpace space) {
427643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(gc_state_ == NOT_IN_GC);
427743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(map->instance_type() != MAP_TYPE);
42780c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // If allocation failures are disallowed, we may allocate in a different
42790c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // space when new space is full and the object is not a large object.
42800c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  AllocationSpace retry_space =
42810c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type());
42824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int size = map->instance_size();
4283303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
42844a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  MaybeObject* maybe_result = AllocateRaw(size, space, retry_space);
42854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!maybe_result->ToObject(&result)) return maybe_result;
428627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  // No need for write barrier since object is white and map is in old space.
428764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(map);
428843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
428943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
429043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
429143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::InitializeFunction(JSFunction* function,
4293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              SharedFunctionInfo* shared,
4294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              Object* prototype) {
429543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!prototype->IsMap());
429643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  function->initialize_properties();
429743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  function->initialize_elements();
429843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  function->set_shared(shared);
429926c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org  function->set_code(shared->code());
430043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  function->set_prototype_or_initial_map(prototype);
430143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  function->set_context(undefined_value());
4302394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  function->set_literals_or_bindings(empty_fixed_array());
4303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  function->set_next_function_link(undefined_value());
430443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
430543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
430643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4307303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateFunctionPrototype(JSFunction* function) {
4308e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Make sure to use globals from the function's context, since the function
4309e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // can be from a different context.
4310e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Context* native_context = function->context()->native_context();
4311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Map* new_map;
4312e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (function->shared()->is_generator()) {
4313e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Generator prototypes can share maps since they don't have "constructor"
4314e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // properties.
4315e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    new_map = native_context->generator_object_prototype_map();
4316e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
4317e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Each function prototype gets a fresh map to avoid unwanted sharing of
4318e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // maps between prototypes of different constructors.
4319e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    JSFunction* object_function = native_context->object_function();
4320e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    ASSERT(object_function->has_initial_map());
4321e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    MaybeObject* maybe_map = object_function->initial_map()->Copy();
4322e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (!maybe_map->To(&new_map)) return maybe_map;
4323e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
4324753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
4325303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* prototype;
4326753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  MaybeObject* maybe_prototype = AllocateJSObjectFromMap(new_map);
4327753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
4328753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
4329bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  if (!function->shared()->is_generator()) {
4330e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    MaybeObject* maybe_failure =
4331e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes(
4332e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org            constructor_string(), function, DONT_ENUM);
4333e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (maybe_failure->IsFailure()) return maybe_failure;
4334e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
4335753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
433643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return prototype;
433743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
433843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
433943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4340303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateFunction(Map* function_map,
4341303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                    SharedFunctionInfo* shared,
4342303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                    Object* prototype,
4343303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                    PretenureFlag pretenure) {
4344846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org  AllocationSpace space =
4345846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org      (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
4346303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
4347303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = Allocate(function_map, space);
4348303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
4349303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
4350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  InitializeFunction(JSFunction::cast(result), shared, prototype);
4351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return result;
435243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
435343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
435443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4355303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateArgumentsObject(Object* callee, int length) {
43569a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // To get fast allocation and map sharing for arguments objects we
43579a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // allocate them based on an arguments boilerplate.
435843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4359ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  JSObject* boilerplate;
4360ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int arguments_object_size;
4361ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool strict_mode_callee = callee->IsJSFunction() &&
43621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      !JSFunction::cast(callee)->shared()->is_classic_mode();
4363ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (strict_mode_callee) {
4364ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    boilerplate =
436546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate()->context()->native_context()->
4366ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org            strict_mode_arguments_boilerplate();
4367ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    arguments_object_size = kArgumentsObjectSizeStrict;
4368ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  } else {
4369ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    boilerplate =
437046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate()->context()->native_context()->arguments_boilerplate();
4371ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    arguments_object_size = kArgumentsObjectSize;
4372ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
4373ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
437443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // This calls Copy directly rather than using Heap::AllocateRaw so we
437543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // duplicate the check here.
437679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  ASSERT(AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC);
437743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4378846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org  // Check that the size of the boilerplate matches our
4379846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org  // expectations. The ArgumentsAccessStub::GenerateNewObject relies
4380846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org  // on the size being a known constant.
4381ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(arguments_object_size == boilerplate->map()->instance_size());
4382846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org
4383846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org  // Do the allocation.
4384303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
4385303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result =
4386ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        AllocateRaw(arguments_object_size, NEW_SPACE, OLD_POINTER_SPACE);
4387303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
4388303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
438943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43909bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // Copy the content. The arguments boilerplate doesn't have any
43919bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // fields that point to new space so it's safe to skip the write
43929bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // barrier here.
439330ce411529579186181838984710b0b0980857aaricow@chromium.org  CopyBlock(HeapObject::cast(result)->address(),
439430ce411529579186181838984710b0b0980857aaricow@chromium.org            boilerplate->address(),
4395ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org            JSObject::kHeaderSize);
439643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4397ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Set the length property.
4398ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsLengthIndex,
43995a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                                                Smi::FromInt(length),
44005a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                                                SKIP_WRITE_BARRIER);
4401ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Set the callee property for non-strict mode arguments object only.
4402ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!strict_mode_callee) {
4403ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex,
4404ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                  callee);
4405ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
44065a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
440743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check the state of the object
440843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(JSObject::cast(result)->HasFastProperties());
4409830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ASSERT(JSObject::cast(result)->HasFastObjectElements());
441043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
441143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
441243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
441343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
441443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4415303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
441643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!fun->has_initial_map());
441743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4418911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // First create a new map with the size and number of in-object properties
4419911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // suggested by the function.
4420e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  InstanceType instance_type;
4421e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int instance_size;
4422e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int in_object_properties;
4423e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (fun->shared()->is_generator()) {
4424e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    instance_type = JS_GENERATOR_OBJECT_TYPE;
4425e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    instance_size = JSGeneratorObject::kSize;
4426e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    in_object_properties = 0;
4427e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
4428e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    instance_type = JS_OBJECT_TYPE;
4429e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    instance_size = fun->shared()->CalculateInstanceSize();
4430e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    in_object_properties = fun->shared()->CalculateInObjectProperties();
4431e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
4432304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  Map* map;
4433e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  MaybeObject* maybe_map = AllocateMap(instance_type, instance_size);
4434304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  if (!maybe_map->To(&map)) return maybe_map;
443543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
443643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fetch or allocate prototype.
443743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* prototype;
443843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (fun->has_instance_prototype()) {
443943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    prototype = fun->instance_prototype();
444043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
4441304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun);
4442304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    if (!maybe_prototype->To(&prototype)) return maybe_prototype;
444343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4444911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  map->set_inobject_properties(in_object_properties);
4445911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  map->set_unused_property_fields(in_object_properties);
444643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map->set_prototype(prototype);
4447830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ASSERT(map->has_fast_object_elements());
4448911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
4449bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  if (!fun->shared()->is_generator()) {
4450e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    fun->shared()->StartInobjectSlackTracking(map);
4451e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
44524a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
445343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return map;
445443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
445543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
445643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
445743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::InitializeJSObjectFromMap(JSObject* obj,
445843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                     FixedArray* properties,
445943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                     Map* map) {
446043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  obj->set_properties(properties);
446143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  obj->initialize_elements();
446243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // TODO(1240798): Initialize the object's body using valid initial values
446343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // according to the object's initial map.  For example, if the map's
446443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // instance type is JS_ARRAY_TYPE, the length field should be initialized
44652efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // to a number (e.g. Smi::FromInt(0)) and the elements initialized to a
44662efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // fixed array (e.g. Heap::empty_fixed_array()).  Currently, the object
446743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // verification code has to cope with (temporarily) invalid objects.  See
446843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for example, JSArray::JSArrayVerify).
44694a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  Object* filler;
44704a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // We cannot always fill with one_pointer_filler_map because objects
44714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // created from API functions expect their internal fields to be initialized
44724a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // with undefined_value.
4473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Pre-allocated fields need to be initialized with undefined_value as well
4474c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // so that object accesses before the constructor completes (e.g. in the
4475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // debugger) will not cause a crash.
44764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  if (map->constructor()->IsJSFunction() &&
44774a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org      JSFunction::cast(map->constructor())->shared()->
44784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org          IsInobjectSlackTrackingInProgress()) {
44794a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    // We might want to shrink the object later.
44804a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    ASSERT(obj->GetInternalFieldCount() == 0);
44814a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    filler = Heap::one_pointer_filler_map();
44824a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  } else {
44834a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    filler = Heap::undefined_value();
44844a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  }
4485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  obj->InitializeBody(map, Heap::undefined_value(), filler);
448643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
448743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
448843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4489594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgMaybeObject* Heap::AllocateJSObjectFromMap(
4490594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Map* map, PretenureFlag pretenure, bool allocate_properties) {
449143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // JSFunctions should be allocated using AllocateFunction to be
449243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // properly initialized.
449343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(map->instance_type() != JS_FUNCTION_TYPE);
449443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
449540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  // Both types of global objects should be allocated using
449640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  // AllocateGlobalObject to be properly initialized.
44970b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE);
44980b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE);
44990b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
450043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate the backing storage for the properties.
4501594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  FixedArray* properties;
4502594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (allocate_properties) {
4503594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int prop_size = map->InitialPropertiesLength();
4504594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(prop_size >= 0);
4505594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure);
4506594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (!maybe_properties->To(&properties)) return maybe_properties;
4507594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
4508594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else {
4509594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    properties = empty_fixed_array();
4510303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
451143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
451243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate the JSObject.
45139258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  AllocationSpace space =
45149258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
4515ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE;
4516303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* obj;
45174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  MaybeObject* maybe_obj = Allocate(map, space);
45184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!maybe_obj->To(&obj)) return maybe_obj;
45194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
45204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Initialize the JSObject.
4521594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  InitializeJSObjectFromMap(JSObject::cast(obj), properties, map);
45224e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  ASSERT(JSObject::cast(obj)->HasFastElements() ||
45234e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org         JSObject::cast(obj)->HasExternalArrayElements());
45244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return obj;
45254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
45264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
45274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4528594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgMaybeObject* Heap::AllocateJSObjectFromMapWithAllocationSite(
4529594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Map* map, Handle<AllocationSite> allocation_site) {
45304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // JSFunctions should be allocated using AllocateFunction to be
45314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // properly initialized.
45324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(map->instance_type() != JS_FUNCTION_TYPE);
45334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
45344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Both types of global objects should be allocated using
45354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // AllocateGlobalObject to be properly initialized.
45364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE);
45374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE);
45384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
45394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate the backing storage for the properties.
454010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  int prop_size = map->InitialPropertiesLength();
45414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(prop_size >= 0);
4542594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  FixedArray* properties;
45434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  { MaybeObject* maybe_properties = AllocateFixedArray(prop_size);
4544594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (!maybe_properties->To(&properties)) return maybe_properties;
4545303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
454643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate the JSObject.
45484a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  AllocationSpace space = NEW_SPACE;
45494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE;
45504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* obj;
4551bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  MaybeObject* maybe_obj =
4552bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      AllocateWithAllocationSite(map, space, allocation_site);
45534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!maybe_obj->To(&obj)) return maybe_obj;
45544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
455543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize the JSObject.
4556594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  InitializeJSObjectFromMap(JSObject::cast(obj), properties, map);
4557fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ASSERT(JSObject::cast(obj)->HasFastElements());
455843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return obj;
455943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
456043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
456143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4562303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateJSObject(JSFunction* constructor,
4563303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                    PretenureFlag pretenure) {
456443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate the initial map if absent.
456543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!constructor->has_initial_map()) {
4566303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* initial_map;
4567303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor);
4568303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_initial_map->ToObject(&initial_map)) return maybe_initial_map;
4569303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
457043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    constructor->set_initial_map(Map::cast(initial_map));
457143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Map::cast(initial_map)->set_constructor(constructor);
457243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
457343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate the object based on the constructors initial map.
4574fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  MaybeObject* result = AllocateJSObjectFromMap(
4575fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      constructor->initial_map(), pretenure);
4576303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#ifdef DEBUG
45772abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // Make sure result is NOT a global object if valid.
4578303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* non_failure;
4579303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject());
4580303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#endif
45812abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  return result;
45822abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
45832abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
45842abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
45854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor,
4586bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<AllocationSite> allocation_site) {
45874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate the initial map if absent.
45884a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!constructor->has_initial_map()) {
45894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Object* initial_map;
45904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor);
45914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (!maybe_initial_map->ToObject(&initial_map)) return maybe_initial_map;
45924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
45934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    constructor->set_initial_map(Map::cast(initial_map));
45944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Map::cast(initial_map)->set_constructor(constructor);
45954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
45964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate the object based on the constructors initial map, or the payload
45974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // advice
45984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Map* initial_map = constructor->initial_map();
45994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4600bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Smi* smi = Smi::cast(allocation_site->transition_info());
46014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
46024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  AllocationSiteMode mode = TRACK_ALLOCATION_SITE;
46034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (to_kind != initial_map->elements_kind()) {
460457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    MaybeObject* maybe_new_map = initial_map->AsElementsKind(to_kind);
46054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (!maybe_new_map->To(&initial_map)) return maybe_new_map;
46064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // Possibly alter the mode, since we found an updated elements kind
46074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // in the type info cell.
4608bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    mode = AllocationSite::GetMode(to_kind);
46094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
46104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
46114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  MaybeObject* result;
46124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
46134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    result = AllocateJSObjectFromMapWithAllocationSite(initial_map,
4614bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        allocation_site);
46154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else {
46164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    result = AllocateJSObjectFromMap(initial_map, NOT_TENURED);
46174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
46184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org#ifdef DEBUG
46194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Make sure result is NOT a global object if valid.
46204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* non_failure;
46214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject());
46224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org#endif
46234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return result;
46244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
46254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
46264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4627e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgMaybeObject* Heap::AllocateJSGeneratorObject(JSFunction *function) {
4628e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(function->shared()->is_generator());
4629e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Map *map;
4630e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (function->has_initial_map()) {
4631e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    map = function->initial_map();
4632e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
4633e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Allocate the initial map if absent.
4634e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    MaybeObject* maybe_map = AllocateInitialMap(function);
4635e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (!maybe_map->To(&map)) return maybe_map;
4636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    function->set_initial_map(map);
4637b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    map->set_constructor(function);
4638e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
4639e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE);
4640e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return AllocateJSObjectFromMap(map);
4641e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
4642e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4643e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
464481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.orgMaybeObject* Heap::AllocateJSModule(Context* context, ScopeInfo* scope_info) {
4645ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  // Allocate a fresh map. Modules do not have a prototype.
4646ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  Map* map;
4647ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  MaybeObject* maybe_map = AllocateMap(JS_MODULE_TYPE, JSModule::kSize);
4648ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  if (!maybe_map->To(&map)) return maybe_map;
4649ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  // Allocate the object based on the map.
465081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  JSModule* module;
465181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  MaybeObject* maybe_module = AllocateJSObjectFromMap(map, TENURED);
465281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  if (!maybe_module->To(&module)) return maybe_module;
465381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  module->set_context(context);
465481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  module->set_scope_info(scope_info);
465581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  return module;
4656ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com}
4657ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
4658ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
4659fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgMaybeObject* Heap::AllocateJSArrayAndStorage(
4660fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    ElementsKind elements_kind,
4661fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    int length,
4662fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    int capacity,
4663fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    ArrayStorageAllocationMode mode,
4664fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    PretenureFlag pretenure) {
4665fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure);
4666fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  JSArray* array;
4667fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (!maybe_array->To(&array)) return maybe_array;
4668fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
46694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // TODO(mvstanton): this body of code is duplicate with AllocateJSArrayStorage
46704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // for performance reasons.
46714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(capacity >= length);
46724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4673fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (capacity == 0) {
4674fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    array->set_length(Smi::FromInt(0));
4675fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    array->set_elements(empty_fixed_array());
4676fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    return array;
4677fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
4678fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
4679fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  FixedArrayBase* elms;
4680fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  MaybeObject* maybe_elms = NULL;
4681fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (IsFastDoubleElementsKind(elements_kind)) {
4682fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
4683fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      maybe_elms = AllocateUninitializedFixedDoubleArray(capacity);
4684fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    } else {
4685fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
4686fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity);
4687fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    }
4688fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  } else {
4689830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
4690fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
4691fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      maybe_elms = AllocateUninitializedFixedArray(capacity);
4692fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    } else {
4693fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
4694fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      maybe_elms = AllocateFixedArrayWithHoles(capacity);
4695fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    }
4696fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
4697fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (!maybe_elms->To(&elms)) return maybe_elms;
4698fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
4699fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  array->set_elements(elms);
4700fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  array->set_length(Smi::FromInt(length));
4701fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  return array;
4702fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
4703fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
4704fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
47054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::AllocateJSArrayAndStorageWithAllocationSite(
47064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    ElementsKind elements_kind,
47074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    int length,
47084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    int capacity,
4709bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<AllocationSite> allocation_site,
47104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    ArrayStorageAllocationMode mode) {
47114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  MaybeObject* maybe_array = AllocateJSArrayWithAllocationSite(elements_kind,
4712bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      allocation_site);
47134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  JSArray* array;
47144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!maybe_array->To(&array)) return maybe_array;
47154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return AllocateJSArrayStorage(array, length, capacity, mode);
47164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
47174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
47184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
47194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::AllocateJSArrayStorage(
47204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    JSArray* array,
47214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    int length,
47224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    int capacity,
47234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    ArrayStorageAllocationMode mode) {
47244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(capacity >= length);
47254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
47264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (capacity == 0) {
47274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    array->set_length(Smi::FromInt(0));
47284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    array->set_elements(empty_fixed_array());
47294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return array;
47304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
47314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
47324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  FixedArrayBase* elms;
47334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  MaybeObject* maybe_elms = NULL;
47344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ElementsKind elements_kind = array->GetElementsKind();
47354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (IsFastDoubleElementsKind(elements_kind)) {
47364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
47374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      maybe_elms = AllocateUninitializedFixedDoubleArray(capacity);
47384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    } else {
47394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
47404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity);
47414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
47424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else {
47434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
47444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
47454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      maybe_elms = AllocateUninitializedFixedArray(capacity);
47464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    } else {
47474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
47484a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      maybe_elms = AllocateFixedArrayWithHoles(capacity);
47494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
47504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
47514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!maybe_elms->To(&elms)) return maybe_elms;
47524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
47534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  array->set_elements(elms);
47544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  array->set_length(Smi::FromInt(length));
47554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return array;
47564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
47574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
47584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4759fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgMaybeObject* Heap::AllocateJSArrayWithElements(
4760fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    FixedArrayBase* elements,
4761fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    ElementsKind elements_kind,
4762fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    int length,
4763fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    PretenureFlag pretenure) {
4764fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure);
4765fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  JSArray* array;
4766fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (!maybe_array->To(&array)) return maybe_array;
4767fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
4768fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  array->set_elements(elements);
4769fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  array->set_length(Smi::FromInt(length));
4770830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  array->ValidateElements();
4771fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  return array;
4772fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
4773fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
4774fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
47757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgMaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) {
47767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Allocate map.
47777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // TODO(rossberg): Once we optimize proxies, think about a scheme to share
47787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // maps. Will probably depend on the identity of the handler object, too.
477940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  Map* map;
47807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize);
478140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
47827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  map->set_prototype(prototype);
47837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
47847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Allocate the proxy object.
478534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  JSProxy* result;
47867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
478734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (!maybe_result->To<JSProxy>(&result)) return maybe_result;
478834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  result->InitializeBody(map->instance_size(), Smi::FromInt(0));
478934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  result->set_handler(handler);
479027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  result->set_hash(undefined_value(), SKIP_WRITE_BARRIER);
479134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return result;
479234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
479334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
479434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
479534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgMaybeObject* Heap::AllocateJSFunctionProxy(Object* handler,
479634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org                                           Object* call_trap,
479734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org                                           Object* construct_trap,
479834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org                                           Object* prototype) {
479934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // Allocate map.
480034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // TODO(rossberg): Once we optimize proxies, think about a scheme to share
480134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // maps. Will probably depend on the identity of the handler object, too.
480234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Map* map;
480334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  MaybeObject* maybe_map_obj =
480434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      AllocateMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
480534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
480634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  map->set_prototype(prototype);
480734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
480834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // Allocate the proxy object.
480934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  JSFunctionProxy* result;
481034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
481134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (!maybe_result->To<JSFunctionProxy>(&result)) return maybe_result;
481234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  result->InitializeBody(map->instance_size(), Smi::FromInt(0));
481334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  result->set_handler(handler);
481427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  result->set_hash(undefined_value(), SKIP_WRITE_BARRIER);
481534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  result->set_call_trap(call_trap);
481634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  result->set_construct_trap(construct_trap);
48177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  return result;
48187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
48197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
48207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
4821303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
48222abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ASSERT(constructor->has_initial_map());
48230b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  Map* map = constructor->initial_map();
482488767247437a4504f433cc5abea22a473e5ed982erik.corry@gmail.com  ASSERT(map->is_dictionary_map());
48250b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
48262abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // Make sure no field properties are described in the initial map.
48272abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // This guarantees us that normalizing the properties does not
4828b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // require us to change property values to PropertyCells.
48290b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ASSERT(map->NextFreePropertyIndex() == 0);
48302abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
48312abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // Make sure we don't have a ton of pre-allocated slots in the
48322abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // global objects. They will be unused once we normalize the object.
48330b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ASSERT(map->unused_property_fields() == 0);
48340b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ASSERT(map->inobject_properties() == 0);
48350b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
48360b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Initial size of the backing store to avoid resize of the storage during
48370b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // bootstrapping. The size differs between the JS global object ad the
48380b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // builtins object.
48390b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512;
48400b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
48410b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Allocate a dictionary object for backing storage.
4842750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  NameDictionary* dictionary;
4843b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  MaybeObject* maybe_dictionary =
4844750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      NameDictionary::Allocate(
48456e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org          this,
484633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org          map->NumberOfOwnDescriptors() * 2 + initial_size);
4847b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
48480b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
48490b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // The global object might be created from an object template with accessors.
48500b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Fill these accessors into the dictionary.
48510b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  DescriptorArray* descs = map->instance_descriptors();
485257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
4853ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    PropertyDetails details = descs->GetDetails(i);
48540b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    ASSERT(details.type() == CALLBACKS);  // Only accessors are expected.
485557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i + 1);
48560b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    Object* value = descs->GetCallbacksObject(i);
4857b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    MaybeObject* maybe_value = AllocatePropertyCell(value);
4858b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    if (!maybe_value->ToObject(&value)) return maybe_value;
48590b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
4860b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    MaybeObject* maybe_added = dictionary->Add(descs->GetKey(i), value, d);
4861b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    if (!maybe_added->To(&dictionary)) return maybe_added;
48620b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  }
48632abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
48640b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Allocate the global object and initialize it with the backing store.
4865b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  JSObject* global;
4866b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  MaybeObject* maybe_global = Allocate(map, OLD_POINTER_SPACE);
4867b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  if (!maybe_global->To(&global)) return maybe_global;
4868b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
48690b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  InitializeJSObjectFromMap(global, dictionary, map);
48702abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
48710b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Create a new map for the global object.
4872657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  Map* new_map;
4873b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  MaybeObject* maybe_map = map->CopyDropDescriptors();
4874b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  if (!maybe_map->To(&new_map)) return maybe_map;
487588767247437a4504f433cc5abea22a473e5ed982erik.corry@gmail.com  new_map->set_dictionary_map(true);
48760b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
4877f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up the global object as a normalized object.
48780b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  global->set_map(new_map);
48790b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  global->set_properties(dictionary);
48802abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
48812abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // Make sure result is a global object with properties in dictionary.
48822abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ASSERT(global->IsGlobalObject());
48832abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ASSERT(!global->HasFastProperties());
48842abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  return global;
488543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
488643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
488743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48884a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::CopyJSObject(JSObject* source) {
48895a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Never used to copy functions.  If functions need to be copied we
48905a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // have to be careful to clear the literals array.
4891394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  SLOW_ASSERT(!source->IsJSFunction());
48925a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
48935a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Make the clone.
48945a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  Map* map = source->map();
48955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  int object_size = map->instance_size();
48969bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  Object* clone;
48979bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
48984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
48994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
49004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // If we're forced to always allocate, we use the general allocation
49014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // functions which may leave us with an object in old space.
49024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (always_allocate()) {
49034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    { MaybeObject* maybe_clone =
49044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE);
49054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (!maybe_clone->ToObject(&clone)) return maybe_clone;
49064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
49074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Address clone_address = HeapObject::cast(clone)->address();
49084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    CopyBlock(clone_address,
49094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              source->address(),
49104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              object_size);
49114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // Update write barrier for all fields that lie beyond the header.
49124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    RecordWrites(clone_address,
49134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                 JSObject::kHeaderSize,
49144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                 (object_size - JSObject::kHeaderSize) / kPointerSize);
49154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else {
49164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    wb_mode = SKIP_WRITE_BARRIER;
49174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
49184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    { MaybeObject* maybe_clone = new_space_.AllocateRaw(object_size);
49194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (!maybe_clone->ToObject(&clone)) return maybe_clone;
49204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
49214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    SLOW_ASSERT(InNewSpace(clone));
49224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // Since we know the clone is allocated in new space, we can copy
49234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // the contents without worrying about updating the write barrier.
49244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    CopyBlock(HeapObject::cast(clone)->address(),
49254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              source->address(),
49264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              object_size);
49274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
492846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
49294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  SLOW_ASSERT(
49304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      JSObject::cast(clone)->GetElementsKind() == source->GetElementsKind());
49314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
49324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  FixedArray* properties = FixedArray::cast(source->properties());
49334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Update elements if necessary.
49344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (elements->length() > 0) {
49354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Object* elem;
49364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    { MaybeObject* maybe_elem;
49374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (elements->map() == fixed_cow_array_map()) {
49384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        maybe_elem = FixedArray::cast(elements);
49394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      } else if (source->HasFastDoubleElements()) {
49404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        maybe_elem = CopyFixedDoubleArray(FixedDoubleArray::cast(elements));
49414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      } else {
49424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        maybe_elem = CopyFixedArray(FixedArray::cast(elements));
49434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      }
49444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (!maybe_elem->ToObject(&elem)) return maybe_elem;
49454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
49464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    JSObject::cast(clone)->set_elements(FixedArrayBase::cast(elem), wb_mode);
49474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
49484a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Update properties if necessary.
49494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (properties->length() > 0) {
49504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Object* prop;
49514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    { MaybeObject* maybe_prop = CopyFixedArray(properties);
49524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (!maybe_prop->ToObject(&prop)) return maybe_prop;
49534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
49544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    JSObject::cast(clone)->set_properties(FixedArray::cast(prop), wb_mode);
49554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
49564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Return the new clone.
49574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return clone;
49584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
49594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
49604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4961bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgMaybeObject* Heap::CopyJSObjectWithAllocationSite(
4962bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    JSObject* source,
4963bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    AllocationSite* site) {
49644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Never used to copy functions.  If functions need to be copied we
49654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // have to be careful to clear the literals array.
49664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  SLOW_ASSERT(!source->IsJSFunction());
49674a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
49684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Make the clone.
49694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Map* map = source->map();
49704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int object_size = map->instance_size();
49714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* clone;
49724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
49738dec82379e3dc6c6a3292879ba64f8bee40d2d98jkummerow@chromium.org  ASSERT(AllocationSite::CanTrack(map->instance_type()));
49744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(map->instance_type() == JS_ARRAY_TYPE);
4975394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
4976394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
49779bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // If we're forced to always allocate, we use the general allocation
49789bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // functions which may leave us with an object in old space.
497946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  int adjusted_object_size = object_size;
49809bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  if (always_allocate()) {
498146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    // We'll only track origin if we are certain to allocate in new space
49824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    const int kMinFreeNewSpaceAfterGC = InitialSemiSpaceSize() * 3/4;
4983ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if ((object_size + AllocationMemento::kSize) < kMinFreeNewSpaceAfterGC) {
4984ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      adjusted_object_size += AllocationMemento::kSize;
498546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    }
498646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
4987303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    { MaybeObject* maybe_clone =
498846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org          AllocateRaw(adjusted_object_size, NEW_SPACE, OLD_POINTER_SPACE);
4989303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_clone->ToObject(&clone)) return maybe_clone;
4990303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
49919bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    Address clone_address = HeapObject::cast(clone)->address();
499230ce411529579186181838984710b0b0980857aaricow@chromium.org    CopyBlock(clone_address,
499330ce411529579186181838984710b0b0980857aaricow@chromium.org              source->address(),
49949bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org              object_size);
49959bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    // Update write barrier for all fields that lie beyond the header.
49964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    int write_barrier_offset = adjusted_object_size > object_size
4997ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        ? JSArray::kSize + AllocationMemento::kSize
49984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        : JSObject::kHeaderSize;
49994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (((object_size - write_barrier_offset) / kPointerSize) > 0) {
50004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      RecordWrites(clone_address,
50014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                   write_barrier_offset,
50024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                   (object_size - write_barrier_offset) / kPointerSize);
50034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
50044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
50054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // Track allocation site information, if we failed to allocate it inline.
50064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (InNewSpace(clone) &&
50074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        adjusted_object_size == object_size) {
5008ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      MaybeObject* maybe_alloc_memento =
5009ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org          AllocateStruct(ALLOCATION_MEMENTO_TYPE);
5010ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      AllocationMemento* alloc_memento;
5011ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      if (maybe_alloc_memento->To(&alloc_memento)) {
5012ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        alloc_memento->set_map_no_write_barrier(allocation_memento_map());
5013ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        alloc_memento->set_allocation_site(site, SKIP_WRITE_BARRIER);
50144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      }
50154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
50169bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  } else {
5017394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    wb_mode = SKIP_WRITE_BARRIER;
5018ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    adjusted_object_size += AllocationMemento::kSize;
501946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
502046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    { MaybeObject* maybe_clone = new_space_.AllocateRaw(adjusted_object_size);
5021303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_clone->ToObject(&clone)) return maybe_clone;
5022303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
5023394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    SLOW_ASSERT(InNewSpace(clone));
50249bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    // Since we know the clone is allocated in new space, we can copy
50253291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    // the contents without worrying about updating the write barrier.
502630ce411529579186181838984710b0b0980857aaricow@chromium.org    CopyBlock(HeapObject::cast(clone)->address(),
502730ce411529579186181838984710b0b0980857aaricow@chromium.org              source->address(),
50289bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org              object_size);
50299bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
50305a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
503146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  if (adjusted_object_size > object_size) {
5032ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
503346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org        reinterpret_cast<Address>(clone) + object_size);
5034ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    alloc_memento->set_map_no_write_barrier(allocation_memento_map());
5035ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    alloc_memento->set_allocation_site(site, SKIP_WRITE_BARRIER);
503646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  }
503746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
5038394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  SLOW_ASSERT(
5039394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      JSObject::cast(clone)->GetElementsKind() == source->GetElementsKind());
50402c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
50415a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  FixedArray* properties = FixedArray::cast(source->properties());
50425a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Update elements if necessary.
5043b26c50a70863498de657ad44be2cffa49ccdcbeaager@chromium.org  if (elements->length() > 0) {
5044303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* elem;
50452c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    { MaybeObject* maybe_elem;
50462c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      if (elements->map() == fixed_cow_array_map()) {
50472c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        maybe_elem = FixedArray::cast(elements);
50482c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      } else if (source->HasFastDoubleElements()) {
50492c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        maybe_elem = CopyFixedDoubleArray(FixedDoubleArray::cast(elements));
50502c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      } else {
50512c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        maybe_elem = CopyFixedArray(FixedArray::cast(elements));
50522c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      }
5053303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_elem->ToObject(&elem)) return maybe_elem;
5054303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
5055394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    JSObject::cast(clone)->set_elements(FixedArrayBase::cast(elem), wb_mode);
50565a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
50575a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Update properties if necessary.
50585a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  if (properties->length() > 0) {
5059303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* prop;
5060303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    { MaybeObject* maybe_prop = CopyFixedArray(properties);
5061303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_prop->ToObject(&prop)) return maybe_prop;
5062303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
5063394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    JSObject::cast(clone)->set_properties(FixedArray::cast(prop), wb_mode);
50645a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
50655a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Return the new clone.
50665a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return clone;
50675a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
50685a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
50695a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
507034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgMaybeObject* Heap::ReinitializeJSReceiver(
507134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    JSReceiver* object, InstanceType type, int size) {
5072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(type >= FIRST_JS_OBJECT_TYPE);
507334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
5074717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  // Allocate fresh map.
5075717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  // TODO(rossberg): Once we optimize proxies, cache these maps.
5076717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  Map* map;
5077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MaybeObject* maybe = AllocateMap(type, size);
5078c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!maybe->To<Map>(&map)) return maybe;
5079717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
508034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // Check that the receiver has at least the size of the fresh object.
508134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  int size_difference = object->map()->instance_size() - map->instance_size();
508234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(size_difference >= 0);
5083717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
5084717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  map->set_prototype(object->map()->prototype());
5085717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
5086717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  // Allocate the backing storage for the properties.
5087717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  int prop_size = map->unused_property_fields() - map->inobject_properties();
5088717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  Object* properties;
5089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  maybe = AllocateFixedArray(prop_size, TENURED);
5090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!maybe->ToObject(&properties)) return maybe;
5091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Functions require some allocation, which might fail here.
5093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SharedFunctionInfo* shared = NULL;
5094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (type == JS_FUNCTION_TYPE) {
5095c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    String* name;
50964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    maybe =
50974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        InternalizeOneByteString(STATIC_ASCII_VECTOR("<freezing call trap>"));
5098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!maybe->To<String>(&name)) return maybe;
5099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    maybe = AllocateSharedFunctionInfo(name);
5100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!maybe->To<SharedFunctionInfo>(&shared)) return maybe;
5101717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  }
5102717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
5103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Because of possible retries of this function after failure,
5104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // we must NOT fail after this point, where we have changed the type!
5105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5106717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  // Reset the map for the object.
5107717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  object->set_map(map);
5108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  JSObject* jsobj = JSObject::cast(object);
5109717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
5110717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  // Reinitialize the object from the constructor map.
5111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  InitializeJSObjectFromMap(jsobj, FixedArray::cast(properties), map);
511234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
511334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // Functions require some minimal initialization.
511434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (type == JS_FUNCTION_TYPE) {
5115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    map->set_function_with_prototype(true);
5116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    InitializeFunction(JSFunction::cast(object), shared, the_hole_value());
5117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    JSFunction::cast(object)->set_context(
511846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate()->context()->native_context());
511934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
512034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
512134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // Put in filler if the new object is smaller than the old.
512234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (size_difference > 0) {
512334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    CreateFillerObjectAt(
512434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org        object->address() + map->instance_size(), size_difference);
512534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
512634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
5127717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  return object;
5128717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org}
5129717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
5130717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
5131303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor,
5132303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                             JSGlobalProxy* object) {
51334a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  ASSERT(constructor->has_initial_map());
513443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Map* map = constructor->initial_map();
513543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51364a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // Check that the already allocated object has the same size and type as
513743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // objects allocated using the constructor.
513843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(map->instance_size() == object->map()->instance_size());
51394a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  ASSERT(map->instance_type() == object->map()->instance_type());
514043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
514143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate the backing storage for the properties.
51427c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  int prop_size = map->unused_property_fields() - map->inobject_properties();
5143303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* properties;
5144303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, TENURED);
5145303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_properties->ToObject(&properties)) return maybe_properties;
5146303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
514743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
514843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Reset the map for the object.
514943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  object->set_map(constructor->initial_map());
515043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
515143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Reinitialize the object from the constructor map.
515243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  InitializeJSObjectFromMap(object, FixedArray::cast(properties), map);
515343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return object;
515443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
515543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
515643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
515759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgMaybeObject* Heap::AllocateStringFromOneByte(Vector<const uint8_t> string,
5158303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                           PretenureFlag pretenure) {
515956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  int length = string.length();
516056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  if (length == 1) {
516155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    return Heap::LookupSingleCharacterStringFromCode(string[0]);
516255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
5163303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5164303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result =
51658e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        AllocateRawOneByteString(string.length(), pretenure);
5166303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5167303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
516843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
516943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Copy the characters into the new object.
517059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  CopyChars(SeqOneByteString::cast(result)->GetChars(),
517159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org            string.start(),
517259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org            length);
517343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
517443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
517543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
517643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgMaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
517889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                                              int non_ascii_start,
51799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                              PretenureFlag pretenure) {
518089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // Continue counting the number of characters in the UTF-8 string, starting
518189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // from the first non-ascii character or word.
5182a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  Access<UnicodeCache::Utf8Decoder>
5183a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org      decoder(isolate_->unicode_cache()->utf8_decoder());
5184a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  decoder->Reset(string.start() + non_ascii_start,
5185a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                 string.length() - non_ascii_start);
5186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int utf16_length = decoder->Utf16Length();
5187a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(utf16_length > 0);
5188a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Allocate string.
5189303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5190a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  {
5191a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    int chars = non_ascii_start + utf16_length;
5192a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    MaybeObject* maybe_result = AllocateRawTwoByteString(chars, pretenure);
5193303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5194303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
519543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convert and copy the characters into the new object.
519656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  SeqTwoByteString* twobyte = SeqTwoByteString::cast(result);
5197a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Copy ascii portion.
5198a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  uint16_t* data = twobyte->GetChars();
5199a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (non_ascii_start != 0) {
5200a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    const char* ascii_data = string.start();
5201a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    for (int i = 0; i < non_ascii_start; i++) {
5202a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      *data++ = *ascii_data++;
5203154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    }
520443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
5205a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Now write the remainder.
5206a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  decoder->WriteUtf16(data, utf16_length);
520743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
520843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
520943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
521043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5211303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateStringFromTwoByte(Vector<const uc16> string,
5212303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                             PretenureFlag pretenure) {
521343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if the string is an ASCII string.
5214303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
521556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  int length = string.length();
521656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  const uc16* start = string.start();
521743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
521859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (String::IsOneByte(start, length)) {
52198e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    MaybeObject* maybe_result = AllocateRawOneByteString(length, pretenure);
522056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5221fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    CopyChars(SeqOneByteString::cast(result)->GetChars(), start, length);
522259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  } else {  // It's not a one byte string.
522356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    MaybeObject* maybe_result = AllocateRawTwoByteString(length, pretenure);
522456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
522556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length);
522643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
522743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
522843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
522943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
523043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMap* Heap::InternalizedStringMapForString(String* string) {
52324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // If the string is in new space it cannot be used as internalized.
523343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (InNewSpace(string)) return NULL;
523443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Find the corresponding internalized string map for strings.
52361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  switch (string->map()->instance_type()) {
52374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    case STRING_TYPE: return internalized_string_map();
52384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    case ASCII_STRING_TYPE: return ascii_internalized_string_map();
52394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    case CONS_STRING_TYPE: return cons_internalized_string_map();
52404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    case CONS_ASCII_STRING_TYPE: return cons_ascii_internalized_string_map();
52414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    case EXTERNAL_STRING_TYPE: return external_internalized_string_map();
52424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    case EXTERNAL_ASCII_STRING_TYPE:
52434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return external_ascii_internalized_string_map();
5244ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
5245ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      return external_internalized_string_with_one_byte_data_map();
52464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    case SHORT_EXTERNAL_STRING_TYPE:
52474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return short_external_internalized_string_map();
52481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    case SHORT_EXTERNAL_ASCII_STRING_TYPE:
52494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return short_external_ascii_internalized_string_map();
5250ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
5251ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      return short_external_internalized_string_with_one_byte_data_map();
52521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    default: return NULL;  // No match found.
5253ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
525443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
525543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
525643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
525746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgstatic inline void WriteOneByteData(Vector<const char> vector,
525846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                                    uint8_t* chars,
525946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                                    int len) {
526046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  // Only works for ascii.
526146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  ASSERT(vector.length() == len);
5262e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemCopy(chars, vector.start(), len);
526346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
526446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
526546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgstatic inline void WriteTwoByteData(Vector<const char> vector,
526646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                                    uint16_t* chars,
526746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                                    int len) {
526846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  const uint8_t* stream = reinterpret_cast<const uint8_t*>(vector.start());
526946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  unsigned stream_length = vector.length();
527046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  while (stream_length != 0) {
527146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    unsigned consumed = 0;
527246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    uint32_t c = unibrow::Utf8::ValueOf(stream, stream_length, &consumed);
527346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    ASSERT(c != unibrow::Utf8::kBadChar);
527446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    ASSERT(consumed <= stream_length);
527546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    stream_length -= consumed;
527646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    stream += consumed;
527746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
527846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      len -= 2;
527946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      if (len < 0) break;
528046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      *chars++ = unibrow::Utf16::LeadSurrogate(c);
528146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      *chars++ = unibrow::Utf16::TrailSurrogate(c);
528246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    } else {
528346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      len -= 1;
528446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      if (len < 0) break;
528546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      *chars++ = c;
52860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
528743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
528846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  ASSERT(stream_length == 0);
528946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  ASSERT(len == 0);
529046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
529143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5292a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
529346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgstatic inline void WriteOneByteData(String* s, uint8_t* chars, int len) {
529446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  ASSERT(s->length() == len);
529546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  String::WriteToFlat(s, chars, 0, len);
529646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
5297a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
5298e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
529946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgstatic inline void WriteTwoByteData(String* s, uint16_t* chars, int len) {
530046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  ASSERT(s->length() == len);
530146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  String::WriteToFlat(s, chars, 0, len);
530246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
5303a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
5304a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
5305a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgtemplate<bool is_one_byte, typename T>
53064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::AllocateInternalizedStringImpl(
53074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    T t, int chars, uint32_t hash_field) {
5308a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(chars >= 0);
530943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute map and object size.
531043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int size;
531143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Map* map;
531243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5313a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (is_one_byte) {
5314fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (chars > SeqOneByteString::kMaxLength) {
531559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      return Failure::OutOfMemoryException(0x9);
53160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
53174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    map = ascii_internalized_string_map();
5318fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    size = SeqOneByteString::SizeFor(chars);
531943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
53200c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    if (chars > SeqTwoByteString::kMaxLength) {
532159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      return Failure::OutOfMemoryException(0xa);
53220c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
53234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    map = internalized_string_map();
53247c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    size = SeqTwoByteString::SizeFor(chars);
532543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
532643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
532743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate string.
5328303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5329ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize)
5330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE)
5331303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                   : old_data_space_->AllocateRaw(size);
5332303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5333303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
533443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
533564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map);
5336ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Set length and hash fields of the allocated string.
5337870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  String* answer = String::cast(result);
5338ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  answer->set_length(chars);
5339ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  answer->set_hash_field(hash_field);
534043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5341870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  ASSERT_EQ(size, answer->Size());
534243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5343a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (is_one_byte) {
534446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars);
5345a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
534646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars);
534743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
5348870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  return answer;
534943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
535043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
535143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5352a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Need explicit instantiations.
5353a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgtemplate
53544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::AllocateInternalizedStringImpl<true>(String*, int, uint32_t);
5355a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgtemplate
53564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::AllocateInternalizedStringImpl<false>(
53574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    String*, int, uint32_t);
5358a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgtemplate
53594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::AllocateInternalizedStringImpl<false>(
53604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Vector<const char>, int, uint32_t);
5361a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
5362a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
53638e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgMaybeObject* Heap::AllocateRawOneByteString(int length,
53648e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                            PretenureFlag pretenure) {
5365fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (length < 0 || length > SeqOneByteString::kMaxLength) {
536659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0xb);
53670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
5368fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  int size = SeqOneByteString::SizeFor(length);
5369fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ASSERT(size <= SeqOneByteString::kMaxSize);
53700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
53710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  AllocationSpace retry_space = OLD_DATA_SPACE;
537243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5373c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (size > Page::kMaxNonCodeHeapObjectSize) {
5374c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    // Allocate in large object space, retry space will be ignored.
53750c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    space = LO_SPACE;
53765aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
5377c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
5378303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5379303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = AllocateRaw(size, space, retry_space);
5380303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5381303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
538243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
538343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Partially initialize the object.
538464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(ascii_string_map());
538543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  String::cast(result)->set_length(length);
5386ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  String::cast(result)->set_hash_field(String::kEmptyHashField);
538743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT_EQ(size, HeapObject::cast(result)->Size());
538815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org
538943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
539043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
539143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
539243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5393303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateRawTwoByteString(int length,
5394303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                            PretenureFlag pretenure) {
53950c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  if (length < 0 || length > SeqTwoByteString::kMaxLength) {
539659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0xc);
53970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
53987c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  int size = SeqTwoByteString::SizeFor(length);
53990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  ASSERT(size <= SeqTwoByteString::kMaxSize);
54000c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
54010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  AllocationSpace retry_space = OLD_DATA_SPACE;
540243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5403c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (size > Page::kMaxNonCodeHeapObjectSize) {
5404c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    // Allocate in large object space, retry space will be ignored.
54050c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    space = LO_SPACE;
54065aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
5407c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
5408303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5409303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = AllocateRaw(size, space, retry_space);
5410303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5411303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
541243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
541343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Partially initialize the object.
541464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(string_map());
541543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  String::cast(result)->set_length(length);
5416ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  String::cast(result)->set_hash_field(String::kEmptyHashField);
541743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT_EQ(size, HeapObject::cast(result)->Size());
541843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
541943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
542043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
542143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5422fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgMaybeObject* Heap::AllocateJSArray(
5423fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    ElementsKind elements_kind,
5424fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    PretenureFlag pretenure) {
542546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* native_context = isolate()->context()->native_context();
542646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  JSFunction* array_function = native_context->array_function();
5427fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Map* map = array_function->initial_map();
5428906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  Map* transition_map = isolate()->get_initial_js_array_map(elements_kind);
5429906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  if (transition_map != NULL) map = transition_map;
5430fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  return AllocateJSObjectFromMap(map, pretenure);
5431fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
5432fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
5433fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
54344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::AllocateJSArrayWithAllocationSite(
54354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    ElementsKind elements_kind,
5436bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<AllocationSite> allocation_site) {
54374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Context* native_context = isolate()->context()->native_context();
54384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  JSFunction* array_function = native_context->array_function();
54394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Map* map = array_function->initial_map();
54404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* maybe_map_array = native_context->js_array_maps();
54414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!maybe_map_array->IsUndefined()) {
54424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Object* maybe_transitioned_map =
54434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        FixedArray::cast(maybe_map_array)->get(elements_kind);
54444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (!maybe_transitioned_map->IsUndefined()) {
54454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      map = Map::cast(maybe_transitioned_map);
54464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
54474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
5448bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  return AllocateJSObjectFromMapWithAllocationSite(map, allocation_site);
54494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
54504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
54514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
5452303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateEmptyFixedArray() {
545343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int size = FixedArray::SizeFor(0);
5454303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5455303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result =
5456303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
5457303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5458303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
545943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize the object.
546064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  reinterpret_cast<FixedArray*>(result)->set_map_no_write_barrier(
546164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      fixed_array_map());
546230ce411529579186181838984710b0b0980857aaricow@chromium.org  reinterpret_cast<FixedArray*>(result)->set_length(0);
546343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
546443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
546543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5466e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
54674e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgMaybeObject* Heap::AllocateEmptyExternalArray(ExternalArrayType array_type) {
54684e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  return AllocateExternalArray(0, array_type, NULL, TENURED);
54694e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
54704e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
547143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5472303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateRawFixedArray(int length) {
54730c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  if (length < 0 || length > FixedArray::kMaxLength) {
547459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0xd);
54750c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
54764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  ASSERT(length > 0);
54779bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // Use the general function if we're forced to always allocate.
5478c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  if (always_allocate()) return AllocateFixedArray(length, TENURED);
54795a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Allocate the raw data for a fixed array.
54805a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  int size = FixedArray::SizeFor(length);
5481c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return size <= Page::kMaxNonCodeHeapObjectSize
54825aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      ? new_space_.AllocateRaw(size)
5483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      : lo_space_->AllocateRaw(size, NOT_EXECUTABLE);
54845a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
54855a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
54865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
5487303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
54885a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  int len = src->length();
5489303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* obj;
5490303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateRawFixedArray(len);
5491303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
5492303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
5493ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (InNewSpace(obj)) {
54945a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    HeapObject* dst = HeapObject::cast(obj);
549564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    dst->set_map_no_write_barrier(map);
54964a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    CopyBlock(dst->address() + kPointerSize,
54974a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org              src->address() + kPointerSize,
54984a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org              FixedArray::SizeFor(len) - kPointerSize);
54995a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    return obj;
55005a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
550164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  HeapObject::cast(obj)->set_map_no_write_barrier(map);
55025a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  FixedArray* result = FixedArray::cast(obj);
55035a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  result->set_length(len);
5504b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
55055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Copy the content
550679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
5507b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
55085a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
55095a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return result;
55105a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
55115a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
55125a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
55132c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.orgMaybeObject* Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src,
55142c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org                                               Map* map) {
55152c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  int len = src->length();
55162c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  Object* obj;
55172c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  { MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(len, NOT_TENURED);
55182c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
55192c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  }
55202c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  HeapObject* dst = HeapObject::cast(obj);
552164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  dst->set_map_no_write_barrier(map);
55222c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  CopyBlock(
55232c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      dst->address() + FixedDoubleArray::kLengthOffset,
55242c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      src->address() + FixedDoubleArray::kLengthOffset,
55252c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset);
55262c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  return obj;
55272c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org}
55282c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
55292c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
5530303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateFixedArray(int length) {
5531911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  ASSERT(length >= 0);
55323291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  if (length == 0) return empty_fixed_array();
5533303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5534303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result = AllocateRawFixedArray(length);
5535303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
55365a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
5537303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Initialize header.
5538303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  FixedArray* array = reinterpret_cast<FixedArray*>(result);
553964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  array->set_map_no_write_barrier(fixed_array_map());
5540303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  array->set_length(length);
5541303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Initialize body.
5542ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(!InNewSpace(undefined_value()));
5543303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MemsetPointer(array->data_start(), undefined_value(), length);
55445a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return result;
55455a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
55465a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
55475a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
5548303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) {
55490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  if (length < 0 || length > FixedArray::kMaxLength) {
555059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0xe);
55510c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
5552c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int size = FixedArray::SizeFor(length);
55530c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  AllocationSpace space =
55540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
5555c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  AllocationSpace retry_space = OLD_POINTER_SPACE;
5556c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
5557c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (size > Page::kMaxNonCodeHeapObjectSize) {
5558c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    // Allocate in large object space, retry space will be ignored.
55590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    space = LO_SPACE;
55600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
55610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
556230ce411529579186181838984710b0b0980857aaricow@chromium.org  return AllocateRaw(size, space, retry_space);
5563c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
5564c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
5565c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
5566303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMUST_USE_RESULT static MaybeObject* AllocateFixedArrayWithFiller(
5567ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Heap* heap,
5568303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    int length,
5569303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    PretenureFlag pretenure,
5570303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* filler) {
5571c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  ASSERT(length >= 0);
5572ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(heap->empty_fixed_array()->IsFixedArray());
5573ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (length == 0) return heap->empty_fixed_array();
5574c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
5575ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(!heap->InNewSpace(filler));
5576303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5577ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_result = heap->AllocateRawFixedArray(length, pretenure);
5578303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5579303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
55800c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
558164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(heap->fixed_array_map());
558243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FixedArray* array = FixedArray::cast(result);
558343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  array->set_length(length);
5584c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  MemsetPointer(array->data_start(), filler, length);
558543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return array;
558643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
558743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
558843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5589303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
5590ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return AllocateFixedArrayWithFiller(this,
5591ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      length,
5592ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      pretenure,
5593ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      undefined_value());
5594c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
5595c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
5596c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
5597303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateFixedArrayWithHoles(int length,
5598303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                               PretenureFlag pretenure) {
5599ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return AllocateFixedArrayWithFiller(this,
5600ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      length,
5601ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      pretenure,
5602ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      the_hole_value());
5603c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
5604c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
5605c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
5606303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateUninitializedFixedArray(int length) {
5607ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (length == 0) return empty_fixed_array();
5608ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
5609303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* obj;
5610303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = AllocateRawFixedArray(length);
5611303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
5612303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
5613ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
561464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  reinterpret_cast<FixedArray*>(obj)->set_map_no_write_barrier(
561564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      fixed_array_map());
5616ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  FixedArray::cast(obj)->set_length(length);
5617ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return obj;
5618ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
5619ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
5620ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
56216d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgMaybeObject* Heap::AllocateEmptyFixedDoubleArray() {
56226d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  int size = FixedDoubleArray::SizeFor(0);
56236d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Object* result;
56246d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  { MaybeObject* maybe_result =
56256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
56266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
56276d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
56286d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // Initialize the object.
562964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  reinterpret_cast<FixedDoubleArray*>(result)->set_map_no_write_barrier(
56306d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      fixed_double_array_map());
56316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  reinterpret_cast<FixedDoubleArray*>(result)->set_length(0);
56326d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return result;
56336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
56346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
56356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
56366d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgMaybeObject* Heap::AllocateUninitializedFixedDoubleArray(
56376d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int length,
56386d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    PretenureFlag pretenure) {
563965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  if (length == 0) return empty_fixed_array();
56406d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
5641fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Object* elements_object;
5642fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(length, pretenure);
5643fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (!maybe_obj->ToObject(&elements_object)) return maybe_obj;
5644fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  FixedDoubleArray* elements =
5645fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      reinterpret_cast<FixedDoubleArray*>(elements_object);
5646fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
5647fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  elements->set_map_no_write_barrier(fixed_double_array_map());
5648fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  elements->set_length(length);
5649fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  return elements;
5650fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
5651fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
5652fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
5653fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgMaybeObject* Heap::AllocateFixedDoubleArrayWithHoles(
5654fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    int length,
5655fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    PretenureFlag pretenure) {
565665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  if (length == 0) return empty_fixed_array();
5657fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
5658fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Object* elements_object;
5659fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(length, pretenure);
5660fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (!maybe_obj->ToObject(&elements_object)) return maybe_obj;
5661fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  FixedDoubleArray* elements =
5662fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      reinterpret_cast<FixedDoubleArray*>(elements_object);
5663fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
5664fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  for (int i = 0; i < length; ++i) {
5665fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    elements->set_the_hole(i);
56666d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
56676d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
5668fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  elements->set_map_no_write_barrier(fixed_double_array_map());
5669fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  elements->set_length(length);
5670fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  return elements;
56716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
56726d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
56736d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
56746d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgMaybeObject* Heap::AllocateRawFixedDoubleArray(int length,
56756d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                               PretenureFlag pretenure) {
56766d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (length < 0 || length > FixedDoubleArray::kMaxLength) {
567759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0xf);
56786d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
56796d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  int size = FixedDoubleArray::SizeFor(length);
5680c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
5681c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  AllocationSpace retry_space = OLD_DATA_SPACE;
5682ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
5683ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com#ifndef V8_HOST_ARCH_64_BIT
5684ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  size += kPointerSize;
5685ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com#endif
5686ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
5687c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (size > Page::kMaxNonCodeHeapObjectSize) {
5688c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    // Allocate in large object space, retry space will be ignored.
56896d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    space = LO_SPACE;
56906d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
56916d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
5692ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  HeapObject* object;
5693ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  { MaybeObject* maybe_object = AllocateRaw(size, space, retry_space);
5694ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (!maybe_object->To<HeapObject>(&object)) return maybe_object;
5695ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
5696ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
5697ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  return EnsureDoubleAligned(this, object, size);
56986d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
56996d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
57006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
5701303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) {
5702303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5703ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure);
5704303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5705303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
570664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(
570764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      hash_table_map());
570886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  ASSERT(result->IsHashTable());
570943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
571043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
571143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
571243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5713f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgMaybeObject* Heap::AllocateSymbol() {
57144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Statically ensure that it is safe to allocate symbols in paged spaces.
57154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  STATIC_ASSERT(Symbol::kSize <= Page::kNonCodeObjectAreaSize);
57164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
57174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* result;
5718f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  MaybeObject* maybe =
5719f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      AllocateRaw(Symbol::kSize, OLD_POINTER_SPACE, OLD_POINTER_SPACE);
57204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!maybe->ToObject(&result)) return maybe;
57214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
57224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(symbol_map());
57234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
57244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Generate a random hash value.
57254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int hash;
57264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int attempts = 0;
57274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  do {
57284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    hash = V8::RandomPrivate(isolate()) & Name::kHashBitMask;
57294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    attempts++;
57304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } while (hash == 0 && attempts < 30);
57314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (hash == 0) hash = 1;  // never return 0
57324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
57334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Symbol::cast(result)->set_hash_field(
57344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      Name::kIsNotArrayIndexMask | (hash << Name::kHashShift));
5735f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Symbol::cast(result)->set_name(undefined_value());
57364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
57374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(result->IsSymbol());
57384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return result;
57394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
57404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
57414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
574246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgMaybeObject* Heap::AllocateNativeContext() {
5743303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5744303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_result =
574546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        AllocateFixedArray(Context::NATIVE_CONTEXT_SLOTS);
5746303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5747303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
574843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Context* context = reinterpret_cast<Context*>(result);
574946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_map_no_write_barrier(native_context_map());
5750830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  context->set_js_array_maps(undefined_value());
575146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(context->IsNativeContext());
575243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(result->IsContext());
575343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
575443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
575543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
575643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
575746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgMaybeObject* Heap::AllocateGlobalContext(JSFunction* function,
575846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                         ScopeInfo* scope_info) {
575946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Object* result;
576046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  { MaybeObject* maybe_result =
576146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        AllocateFixedArray(scope_info->ContextLength(), TENURED);
576246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
576346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
576446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* context = reinterpret_cast<Context*>(result);
576546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_map_no_write_barrier(global_context_map());
576646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_closure(function);
5767355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  context->set_previous(function->context());
576846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_extension(scope_info);
5769355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  context->set_global_object(function->context()->global_object());
577046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(context->IsGlobalContext());
577146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(result->IsContext());
577246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return context;
577346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
577446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
577546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
577681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.orgMaybeObject* Heap::AllocateModuleContext(ScopeInfo* scope_info) {
5777ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  Object* result;
5778ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  { MaybeObject* maybe_result =
577981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org        AllocateFixedArray(scope_info->ContextLength(), TENURED);
5780ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (!maybe_result->ToObject(&result)) return maybe_result;
5781ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
5782ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  Context* context = reinterpret_cast<Context*>(result);
5783ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  context->set_map_no_write_barrier(module_context_map());
57848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Instance link will be set later.
578581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  context->set_extension(Smi::FromInt(0));
5786ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  return context;
5787ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com}
5788ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
5789ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
5790303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) {
579143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(length >= Context::MIN_CONTEXT_SLOTS);
5792303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5793ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_result = AllocateFixedArray(length);
5794303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5795303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
579643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Context* context = reinterpret_cast<Context*>(result);
579764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  context->set_map_no_write_barrier(function_context_map());
579843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  context->set_closure(function);
57996d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  context->set_previous(function->context());
580081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  context->set_extension(Smi::FromInt(0));
580146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_global_object(function->context()->global_object());
58026d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return context;
58036d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
58046d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
58056d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
58063cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgMaybeObject* Heap::AllocateCatchContext(JSFunction* function,
58073cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                                        Context* previous,
58086d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                        String* name,
58096d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                        Object* thrown_object) {
58106d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
58116d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Object* result;
58126d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  { MaybeObject* maybe_result =
58136d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        AllocateFixedArray(Context::MIN_CONTEXT_SLOTS + 1);
58146d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
58156d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
58166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Context* context = reinterpret_cast<Context*>(result);
581764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  context->set_map_no_write_barrier(catch_context_map());
58183cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  context->set_closure(function);
58196d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  context->set_previous(previous);
58206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  context->set_extension(name);
582146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_global_object(previous->global_object());
58226d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  context->set(Context::THROWN_OBJECT_INDEX, thrown_object);
58236d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return context;
582443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
582543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
582643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58273cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgMaybeObject* Heap::AllocateWithContext(JSFunction* function,
58283cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                                       Context* previous,
5829ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                       JSReceiver* extension) {
5830303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5831ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS);
5832303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5833303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
583443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Context* context = reinterpret_cast<Context*>(result);
583564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  context->set_map_no_write_barrier(with_context_map());
58363cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  context->set_closure(function);
583743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  context->set_previous(previous);
583843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  context->set_extension(extension);
583946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_global_object(previous->global_object());
58406d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return context;
584143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
584243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
584343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.orgMaybeObject* Heap::AllocateBlockContext(JSFunction* function,
58454acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org                                        Context* previous,
5846c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                        ScopeInfo* scope_info) {
58474acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Object* result;
58484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  { MaybeObject* maybe_result =
5849c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        AllocateFixedArrayWithHoles(scope_info->ContextLength());
58504acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
58514acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
58524acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Context* context = reinterpret_cast<Context*>(result);
585364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  context->set_map_no_write_barrier(block_context_map());
58544acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  context->set_closure(function);
58554acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  context->set_previous(previous);
58564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  context->set_extension(scope_info);
585746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_global_object(previous->global_object());
58584acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  return context;
58594acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
58604acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
58614acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
5862c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgMaybeObject* Heap::AllocateScopeInfo(int length) {
5863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  FixedArray* scope_info;
5864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  MaybeObject* maybe_scope_info = AllocateFixedArray(length, TENURED);
5865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (!maybe_scope_info->To(&scope_info)) return maybe_scope_info;
586664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  scope_info->set_map_no_write_barrier(scope_info_map());
58674acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  return scope_info;
58684acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
58694acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
58704acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
5871eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.orgMaybeObject* Heap::AllocateExternal(void* value) {
5872eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  Foreign* foreign;
5873eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  { MaybeObject* maybe_result = AllocateForeign(static_cast<Address>(value));
5874eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org    if (!maybe_result->To(&foreign)) return maybe_result;
5875eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  }
5876eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  JSObject* external;
5877eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  { MaybeObject* maybe_result = AllocateJSObjectFromMap(external_map());
5878eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org    if (!maybe_result->To(&external)) return maybe_result;
5879eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  }
5880eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  external->SetInternalField(0, foreign);
5881eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  return external;
5882eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org}
5883eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org
5884eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org
5885303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMaybeObject* Heap::AllocateStruct(InstanceType type) {
588643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Map* map;
588743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (type) {
5888ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#define MAKE_CASE(NAME, Name, name) \
5889ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    case NAME##_TYPE: map = name##_map(); break;
589043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenSTRUCT_LIST(MAKE_CASE)
589143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef MAKE_CASE
589243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
589343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      UNREACHABLE();
589443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return Failure::InternalError();
589543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
589643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int size = map->instance_size();
589743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  AllocationSpace space =
5898ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      (size > Page::kMaxNonCodeHeapObjectSize) ? LO_SPACE : OLD_POINTER_SPACE;
5899303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
5900ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_result = Allocate(map, space);
5901303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
5902303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
590343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Struct::cast(result)->InitializeBody(size);
590443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
590543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
590643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
590743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool Heap::IsHeapIterable() {
5909c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return (!old_pointer_space()->was_swept_conservatively() &&
5910c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          !old_data_space()->was_swept_conservatively());
5911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
5912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5914c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::EnsureHeapIsIterable() {
591579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  ASSERT(AllowHeapAllocation::IsAllowed());
5916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!IsHeapIterable()) {
5917994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    CollectAllGarbage(kMakeHeapIterableMask, "Heap::EnsureHeapIsIterable");
5918c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
5919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(IsHeapIterable());
5920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
5921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5922c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
59236ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.orgvoid Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
59247d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  incremental_marking()->Step(step_size,
59257d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org                              IncrementalMarking::NO_GC_VIA_STACK_GUARD);
59266ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
59276ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  if (incremental_marking()->IsComplete()) {
59286ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    bool uncommit = false;
59296ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    if (gc_count_at_last_idle_gc_ == gc_count_) {
59306ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      // No GC since the last full GC, the mutator is probably not active.
59316ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      isolate_->compilation_cache()->Clear();
59326ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      uncommit = true;
59336ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    }
59346ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
5935b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    mark_sweeps_since_idle_round_started_++;
59366ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    gc_count_at_last_idle_gc_ = gc_count_;
59376ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    if (uncommit) {
59386ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      new_space_.Shrink();
59396ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      UncommitFromSpace();
59406ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    }
59416ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  }
59426ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org}
59436ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
59446ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
5945ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.orgbool Heap::IdleNotification(int hint) {
5946de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  // Hints greater than this value indicate that
5947de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  // the embedder is requesting a lot of GC work.
594888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  const int kMaxHint = 1000;
5949b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  const int kMinHintForIncrementalMarking = 10;
5950de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  // Minimal hint that allows to do full GC.
5951de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  const int kMinHintForFullGC = 100;
59522c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org  intptr_t size_factor = Min(Max(hint, 20), kMaxHint) / 4;
59532c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org  // The size factor is in range [5..250]. The numbers here are chosen from
59542c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org  // experiments. If you changes them, make sure to test with
59552c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org  // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.*
595633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  intptr_t step_size =
595733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      size_factor * IncrementalMarking::kAllocatedThreshold;
59586ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
59596ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  if (contexts_disposed_ > 0) {
596088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org    if (hint >= kMaxHint) {
596188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      // The embedder is requesting a lot of GC work after context disposal,
596288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      // we age inline caches so that they don't keep objects from
596388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      // the old context alive.
596488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      AgeInlineCaches();
596588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org    }
59666ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000);
596783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    if (hint >= mark_sweep_time && !FLAG_expose_gc &&
596883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org        incremental_marking()->IsStopped()) {
59696ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      HistogramTimerScope scope(isolate_->counters()->gc_context());
59706ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      CollectAllGarbage(kReduceMemoryFootprintMask,
59716ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                        "idle notification: contexts disposed");
59726ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    } else {
59736ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      AdvanceIdleIncrementalMarking(step_size);
59746ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      contexts_disposed_ = 0;
59756ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    }
59762c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org    // After context disposal there is likely a lot of garbage remaining, reset
59772c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org    // the idle notification counters in order to trigger more incremental GCs
59782c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org    // on subsequent idle notifications.
59792c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org    StartIdleRound();
59806ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    return false;
59816ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  }
59826ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
598383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  if (!FLAG_incremental_marking || FLAG_expose_gc || Serializer::enabled()) {
59846ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    return IdleGlobalGC();
5985ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  }
5986ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
5987ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // By doing small chunks of GC work in each IdleNotification,
5988ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // perform a round of incremental GCs and after that wait until
5989ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // the mutator creates enough garbage to justify a new round.
5990ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // An incremental GC progresses as follows:
5991ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // 1. many incremental marking steps,
5992ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // 2. one old space mark-sweep-compact,
5993ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // 3. many lazy sweep steps.
5994ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // Use mark-sweep-compact events to count incremental GCs in a round.
5995ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
5996ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  if (incremental_marking()->IsStopped()) {
5997e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org    if (!mark_compact_collector()->AreSweeperThreadsActivated() &&
5998e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org        !IsSweepingComplete() &&
5999ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org        !AdvanceSweepers(static_cast<int>(step_size))) {
6000ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org      return false;
6001ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org    }
6002ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  }
6003ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
6004ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
6005ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org    if (EnoughGarbageSinceLastIdleRound()) {
6006ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org      StartIdleRound();
6007ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org    } else {
6008ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org      return true;
6009ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org    }
6010ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  }
6011ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
6012de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  int remaining_mark_sweeps = kMaxMarkSweepsInIdleRound -
6013de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                              mark_sweeps_since_idle_round_started_;
6014de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
6015ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  if (incremental_marking()->IsStopped()) {
6016de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // If there are no more than two GCs left in this idle round and we are
6017de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // allowed to do a full GC, then make those GCs full in order to compact
6018de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // the code space.
6019de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // TODO(ulan): Once we enable code compaction for incremental marking,
6020de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // we can get rid of this special case and always start incremental marking.
6021de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    if (remaining_mark_sweeps <= 2 && hint >= kMinHintForFullGC) {
6022de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org      CollectAllGarbage(kReduceMemoryFootprintMask,
6023de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                        "idle notification: finalize idle round");
6024b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      mark_sweeps_since_idle_round_started_++;
6025b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    } else if (hint > kMinHintForIncrementalMarking) {
6026de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org      incremental_marking()->Start();
6027de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    }
6028de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
6029b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  if (!incremental_marking()->IsStopped() &&
6030b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      hint > kMinHintForIncrementalMarking) {
6031de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    AdvanceIdleIncrementalMarking(step_size);
6032ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  }
6033b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
6034b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
6035b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    FinishIdleRound();
6036b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    return true;
6037b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
6038b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
6039ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  return false;
6040ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org}
6041ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
6042ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
6043ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.orgbool Heap::IdleGlobalGC() {
6044a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  static const int kIdlesBeforeScavenge = 4;
6045a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  static const int kIdlesBeforeMarkSweep = 7;
6046a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  static const int kIdlesBeforeMarkCompact = 8;
60475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1;
60483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  static const unsigned int kGCsBetweenCleanup = 4;
6049ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
6050ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!last_idle_notification_gc_count_init_) {
6051ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    last_idle_notification_gc_count_ = gc_count_;
6052ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    last_idle_notification_gc_count_init_ = true;
6053ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
605496c75b57eba103edd76da075b60997bd1faf781eager@chromium.org
6055ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  bool uncommit = true;
605696c75b57eba103edd76da075b60997bd1faf781eager@chromium.org  bool finished = false;
605796c75b57eba103edd76da075b60997bd1faf781eager@chromium.org
60585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Reset the number of idle notifications received when a number of
60595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // GCs have taken place. This allows another round of cleanup based
60605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // on idle notifications if enough work has been carried out to
60615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // provoke a number of garbage collections.
6062ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (gc_count_ - last_idle_notification_gc_count_ < kGCsBetweenCleanup) {
6063ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    number_idle_notifications_ =
6064ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        Min(number_idle_notifications_ + 1, kMaxIdleCount);
606596c75b57eba103edd76da075b60997bd1faf781eager@chromium.org  } else {
6066ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    number_idle_notifications_ = 0;
6067ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    last_idle_notification_gc_count_ = gc_count_;
606896c75b57eba103edd76da075b60997bd1faf781eager@chromium.org  }
606996c75b57eba103edd76da075b60997bd1faf781eager@chromium.org
6070ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (number_idle_notifications_ == kIdlesBeforeScavenge) {
60716ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    CollectGarbage(NEW_SPACE, "idle notification");
6072a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    new_space_.Shrink();
6073ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    last_idle_notification_gc_count_ = gc_count_;
6074ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  } else if (number_idle_notifications_ == kIdlesBeforeMarkSweep) {
6075ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    // Before doing the mark-sweep collections we clear the
6076ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    // compilation cache to avoid hanging on to source code and
6077ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    // generated code for cached functions.
6078ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->compilation_cache()->Clear();
6079ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
6080994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    CollectAllGarbage(kReduceMemoryFootprintMask, "idle notification");
6081a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    new_space_.Shrink();
6082ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    last_idle_notification_gc_count_ = gc_count_;
6083a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
6084ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  } else if (number_idle_notifications_ == kIdlesBeforeMarkCompact) {
6085994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    CollectAllGarbage(kReduceMemoryFootprintMask, "idle notification");
6086a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    new_space_.Shrink();
6087ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    last_idle_notification_gc_count_ = gc_count_;
6088ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    number_idle_notifications_ = 0;
6089a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    finished = true;
6090ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  } else if (number_idle_notifications_ > kIdlesBeforeMarkCompact) {
60915f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // If we have received more than kIdlesBeforeMarkCompact idle
60925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // notifications we do not perform any cleanup because we don't
60935f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // expect to gain much by doing so.
60945f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    finished = true;
609596c75b57eba103edd76da075b60997bd1faf781eager@chromium.org  }
609696c75b57eba103edd76da075b60997bd1faf781eager@chromium.org
6097ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (uncommit) UncommitFromSpace();
6098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
609996c75b57eba103edd76da075b60997bd1faf781eager@chromium.org  return finished;
610096c75b57eba103edd76da075b60997bd1faf781eager@chromium.org}
610196c75b57eba103edd76da075b60997bd1faf781eager@chromium.org
610296c75b57eba103edd76da075b60997bd1faf781eager@chromium.org
610343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
610443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
610543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::Print() {
6106f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return;
6107bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  isolate()->PrintStack(stdout);
61087c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  AllSpaces spaces(this);
61097c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
6110b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    space->Print();
61117c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
611243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
611343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
611443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
611543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ReportCodeStatistics(const char* title) {
611643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF(">>>>>> Code Stats (%s) >>>>>>\n", title);
611743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PagedSpace::ResetCodeStatistics();
611843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We do not look for code in new space, map space, or old space.  If code
611943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // somehow ends up in those spaces, we would miss it here.
612043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  code_space_->CollectCodeStatistics();
612143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  lo_space_->CollectCodeStatistics();
612243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PagedSpace::ReportCodeStatistics();
612343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
612443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
612543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
612643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This function expects that NewSpace's allocated objects histogram is
612743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// populated (via a call to CollectStatistics or else as a side effect of a
612843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// just-completed scavenge collection).
612943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ReportHeapStatistics(const char* title) {
613043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  USE(title);
613143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF(">>>>>> =============== %s (%d) =============== >>>>>>\n",
613243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen         title, gc_count_);
6133a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  PrintF("old_generation_allocation_limit_ %" V8_PTR_PREFIX "d\n",
6134a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org         old_generation_allocation_limit_);
613543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
613643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("\n");
613709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles(isolate_));
6138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->global_handles()->PrintStats();
613943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("\n");
614043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
614143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Heap statistics : ");
6142ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->memory_allocator()->ReportStatistics();
614343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("To space : ");
61445a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  new_space_.ReportStatistics();
61459258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  PrintF("Old pointer space : ");
61469258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  old_pointer_space_->ReportStatistics();
61479258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  PrintF("Old data space : ");
61489258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  old_data_space_->ReportStatistics();
614943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Code space : ");
615043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  code_space_->ReportStatistics();
615143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Map space : ");
615243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map_space_->ReportStatistics();
6153defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  PrintF("Cell space : ");
6154defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  cell_space_->ReportStatistics();
6155b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  PrintF("PropertyCell space : ");
615641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  property_cell_space_->ReportStatistics();
615743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Large object space : ");
615843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  lo_space_->ReportStatistics();
615943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF(">>>>>> ========================================= >>>>>>\n");
616043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
616143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
616243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // DEBUG
616343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
616443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::Contains(HeapObject* value) {
616543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Contains(value->address());
616643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
616743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
616843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
616943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::Contains(Address addr) {
617043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (OS::IsOutsideAllocatedSpace(addr)) return false;
6171f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  return HasBeenSetUp() &&
61725a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    (new_space_.ToSpaceContains(addr) ||
61739258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org     old_pointer_space_->Contains(addr) ||
61749258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org     old_data_space_->Contains(addr) ||
617543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen     code_space_->Contains(addr) ||
617643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen     map_space_->Contains(addr) ||
6177defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org     cell_space_->Contains(addr) ||
617841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org     property_cell_space_->Contains(addr) ||
617943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen     lo_space_->SlowContains(addr));
618043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
618143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
618243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
618343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::InSpace(HeapObject* value, AllocationSpace space) {
618443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return InSpace(value->address(), space);
618543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
618643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
618743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
618843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::InSpace(Address addr, AllocationSpace space) {
618943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (OS::IsOutsideAllocatedSpace(addr)) return false;
6190f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return false;
619143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
619243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (space) {
619343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case NEW_SPACE:
61945a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      return new_space_.ToSpaceContains(addr);
61959258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
61969258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return old_pointer_space_->Contains(addr);
61979258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
61989258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return old_data_space_->Contains(addr);
619943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case CODE_SPACE:
620043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return code_space_->Contains(addr);
620143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case MAP_SPACE:
620243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return map_space_->Contains(addr);
6203defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    case CELL_SPACE:
6204defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      return cell_space_->Contains(addr);
620541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_SPACE:
620641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      return property_cell_space_->Contains(addr);
620743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case LO_SPACE:
620843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return lo_space_->SlowContains(addr);
620943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
621043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
621143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
621243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
621343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
621443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6215c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
621643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::Verify() {
6217c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  CHECK(HasBeenSetUp());
621843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->Verify();
6220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
622143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  VerifyPointersVisitor visitor;
6222c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  IterateRoots(&visitor, VISIT_ONLY_STRONG);
622343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6224defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  new_space_.Verify();
6225defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
6226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  old_pointer_space_->Verify(&visitor);
6227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  map_space_->Verify(&visitor);
622830ce411529579186181838984710b0b0980857aaricow@chromium.org
622930ce411529579186181838984710b0b0980857aaricow@chromium.org  VerifyPointersVisitor no_dirty_regions_visitor;
623030ce411529579186181838984710b0b0980857aaricow@chromium.org  old_data_space_->Verify(&no_dirty_regions_visitor);
623130ce411529579186181838984710b0b0980857aaricow@chromium.org  code_space_->Verify(&no_dirty_regions_visitor);
623230ce411529579186181838984710b0b0980857aaricow@chromium.org  cell_space_->Verify(&no_dirty_regions_visitor);
623341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  property_cell_space_->Verify(&no_dirty_regions_visitor);
6234defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
6235defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  lo_space_->Verify();
6236f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
6237c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
623843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
623943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
62404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::InternalizeUtf8String(Vector<const char> string) {
62414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* result = NULL;
6242303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* new_table;
6243303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_new_table =
62444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        string_table()->LookupUtf8String(string, &result);
6245303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
6246303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
62474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Can't use set_string_table because StringTable::cast knows that
62484a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // StringTable is a singleton and checks for identity.
62494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  roots_[kStringTableRootIndex] = new_table;
62504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(result != NULL);
62514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return result;
625243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
625343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
625443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
62554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::InternalizeOneByteString(Vector<const uint8_t> string) {
62564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* result = NULL;
62579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  Object* new_table;
62589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  { MaybeObject* maybe_new_table =
62594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        string_table()->LookupOneByteString(string, &result);
62609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
62619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
62624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Can't use set_string_table because StringTable::cast knows that
62634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // StringTable is a singleton and checks for identity.
62644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  roots_[kStringTableRootIndex] = new_table;
62654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(result != NULL);
62664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return result;
62679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
62689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
62699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
62704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::InternalizeOneByteString(Handle<SeqOneByteString> string,
627140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                     int from,
627240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                     int length) {
62734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* result = NULL;
627440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  Object* new_table;
627540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  { MaybeObject* maybe_new_table =
62764a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        string_table()->LookupSubStringOneByteString(string,
627740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                                   from,
627840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                                   length,
62794a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                                                   &result);
628040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
628140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  }
62824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Can't use set_string_table because StringTable::cast knows that
62834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // StringTable is a singleton and checks for identity.
62844a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  roots_[kStringTableRootIndex] = new_table;
62854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(result != NULL);
62864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return result;
628740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org}
628840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
628940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
62904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::InternalizeTwoByteString(Vector<const uc16> string) {
62914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* result = NULL;
62929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  Object* new_table;
62939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  { MaybeObject* maybe_new_table =
62944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        string_table()->LookupTwoByteString(string, &result);
62959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
62969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
62974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Can't use set_string_table because StringTable::cast knows that
62984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // StringTable is a singleton and checks for identity.
62994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  roots_[kStringTableRootIndex] = new_table;
63004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(result != NULL);
63014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return result;
63029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
63039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
63049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
63054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgMaybeObject* Heap::InternalizeString(String* string) {
63064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (string->IsInternalizedString()) return string;
63074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Object* result = NULL;
6308303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* new_table;
6309303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_new_table =
63104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        string_table()->LookupString(string, &result);
6311303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
6312303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
63134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Can't use set_string_table because StringTable::cast knows that
63144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // StringTable is a singleton and checks for identity.
63154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  roots_[kStringTableRootIndex] = new_table;
63164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(result != NULL);
63174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return result;
631843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
631943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
632043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
63214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgbool Heap::InternalizeStringIfExists(String* string, String** result) {
63224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (string->IsInternalizedString()) {
63234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    *result = string;
63247c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    return true;
63257c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
63264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return string_table()->LookupStringIfExists(string, result);
63277c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org}
63287c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
6329e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
633043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ZapFromSpace() {
6331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  NewSpacePageIterator it(new_space_.FromSpaceStart(),
6332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          new_space_.FromSpaceEnd());
6333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
6334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    NewSpacePage* page = it.next();
6335ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    for (Address cursor = page->area_start(), limit = page->area_end();
6336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         cursor < limit;
6337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         cursor += kPointerSize) {
6338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Memory::Address_at(cursor) = kFromSpaceZapValue;
6339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
634043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
634143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
634243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
634343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::IterateAndMarkPointersToFromSpace(Address start,
6345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                             Address end,
6346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                             ObjectSlotCallback callback) {
634730ce411529579186181838984710b0b0980857aaricow@chromium.org  Address slot_address = start;
6348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // We are not collecting slots on new space objects during mutation
6350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // thus we have to scan for pointers to evacuation candidates when we
6351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // promote objects. But we should not record any slots in non-black
6352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // objects. Grey object's slots would be rescanned.
6353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // White object might not survive until the end of collection
6354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // it would be a violation of the invariant to record it's slots.
6355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool record_slots = false;
6356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (incremental_marking()->IsCompacting()) {
6357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(HeapObject::FromAddress(start));
6358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    record_slots = Marking::IsBlack(mark_bit);
6359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
636030ce411529579186181838984710b0b0980857aaricow@chromium.org
636130ce411529579186181838984710b0b0980857aaricow@chromium.org  while (slot_address < end) {
636230ce411529579186181838984710b0b0980857aaricow@chromium.org    Object** slot = reinterpret_cast<Object**>(slot_address);
6363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* object = *slot;
6364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the store buffer becomes overfull we mark pages as being exempt from
6365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // the store buffer.  These pages are scanned to find pointers that point
6366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // to the new space.  In that case we may hit newly promoted objects and
6367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // fix the pointers before the promotion queue gets to them.  Thus the 'if'.
6368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (object->IsHeapObject()) {
6369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (Heap::InFromSpace(object)) {
6370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        callback(reinterpret_cast<HeapObject**>(slot),
6371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 HeapObject::cast(object));
6372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        Object* new_object = *slot;
6373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (InNewSpace(new_object)) {
6374394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          SLOW_ASSERT(Heap::InToSpace(new_object));
6375394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          SLOW_ASSERT(new_object->IsHeapObject());
6376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          store_buffer_.EnterDirectlyIntoStoreBuffer(
6377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com              reinterpret_cast<Address>(slot));
6378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
6379394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        SLOW_ASSERT(!MarkCompactCollector::IsOnEvacuationCandidate(new_object));
6380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else if (record_slots &&
6381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 MarkCompactCollector::IsOnEvacuationCandidate(object)) {
6382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        mark_compact_collector()->RecordSlot(slot, slot, object);
638343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
638430ce411529579186181838984710b0b0980857aaricow@chromium.org    }
638530ce411529579186181838984710b0b0980857aaricow@chromium.org    slot_address += kPointerSize;
638630ce411529579186181838984710b0b0980857aaricow@chromium.org  }
638730ce411529579186181838984710b0b0980857aaricow@chromium.org}
638830ce411529579186181838984710b0b0980857aaricow@chromium.org
638930ce411529579186181838984710b0b0980857aaricow@chromium.org
6390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG
6391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comtypedef bool (*CheckStoreBufferFilter)(Object** addr);
639230ce411529579186181838984710b0b0980857aaricow@chromium.org
639330ce411529579186181838984710b0b0980857aaricow@chromium.org
6394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool IsAMapPointerAddress(Object** addr) {
6395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  uintptr_t a = reinterpret_cast<uintptr_t>(addr);
6396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int mod = a % Map::kSize;
6397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return mod >= Map::kPointerFieldsBeginOffset &&
6398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         mod < Map::kPointerFieldsEndOffset;
639930ce411529579186181838984710b0b0980857aaricow@chromium.org}
640030ce411529579186181838984710b0b0980857aaricow@chromium.org
640130ce411529579186181838984710b0b0980857aaricow@chromium.org
6402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool EverythingsAPointer(Object** addr) {
6403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return true;
6404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
640530ce411529579186181838984710b0b0980857aaricow@chromium.org
640630ce411529579186181838984710b0b0980857aaricow@chromium.org
6407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void CheckStoreBuffer(Heap* heap,
6408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Object** current,
6409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Object** limit,
6410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Object**** store_buffer_position,
6411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Object*** store_buffer_top,
6412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             CheckStoreBufferFilter filter,
6413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Address special_garbage_start,
6414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Address special_garbage_end) {
6415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Map* free_space_map = heap->free_space_map();
6416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for ( ; current < limit; current++) {
6417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* o = *current;
6418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Address current_address = reinterpret_cast<Address>(current);
6419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Skip free space.
6420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (o == free_space_map) {
6421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Address current_address = reinterpret_cast<Address>(current);
6422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      FreeSpace* free_space =
6423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          FreeSpace::cast(HeapObject::FromAddress(current_address));
6424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int skip = free_space->Size();
6425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(current_address + skip <= reinterpret_cast<Address>(limit));
6426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(skip > 0);
6427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current_address += skip - kPointerSize;
6428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current = reinterpret_cast<Object**>(current_address);
6429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      continue;
6430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
6431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Skip the current linear allocation space between top and limit which is
6432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // unmarked with the free space map, but can contain junk.
6433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (current_address == special_garbage_start &&
6434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        special_garbage_end != special_garbage_start) {
6435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current_address = special_garbage_end - kPointerSize;
6436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current = reinterpret_cast<Object**>(current_address);
6437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      continue;
6438c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
6439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!(*filter)(current)) continue;
6440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(current_address < special_garbage_start ||
6441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           current_address >= special_garbage_end);
6442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(reinterpret_cast<uintptr_t>(o) != kFreeListZapValue);
6443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // We have to check that the pointer does not point into new space
6444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // without trying to cast it to a heap object since the hash field of
6445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a string can contain values like 1 and 3 which are tagged null
6446c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // pointers.
6447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!heap->InNewSpace(o)) continue;
6448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    while (**store_buffer_position < current &&
6449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           *store_buffer_position < store_buffer_top) {
6450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      (*store_buffer_position)++;
6451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
6452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (**store_buffer_position != current ||
6453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        *store_buffer_position == store_buffer_top) {
6454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object** obj_start = current;
6455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      while (!(*obj_start)->IsMap()) obj_start--;
6456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      UNREACHABLE();
645730ce411529579186181838984710b0b0980857aaricow@chromium.org    }
645830ce411529579186181838984710b0b0980857aaricow@chromium.org  }
645930ce411529579186181838984710b0b0980857aaricow@chromium.org}
646030ce411529579186181838984710b0b0980857aaricow@chromium.org
646130ce411529579186181838984710b0b0980857aaricow@chromium.org
6462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Check that the store buffer contains all intergenerational pointers by
6463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// scanning a page and ensuring that all pointers to young space are in the
6464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// store buffer.
6465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::OldPointerSpaceCheckStoreBuffer() {
6466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  OldSpace* space = old_pointer_space();
6467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PageIterator pages(space);
646830ce411529579186181838984710b0b0980857aaricow@chromium.org
6469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->SortUniq();
647030ce411529579186181838984710b0b0980857aaricow@chromium.org
6471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (pages.has_next()) {
6472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* page = pages.next();
6473ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Object** current = reinterpret_cast<Object**>(page->area_start());
647430ce411529579186181838984710b0b0980857aaricow@chromium.org
6475ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Address end = page->area_end();
647630ce411529579186181838984710b0b0980857aaricow@chromium.org
6477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object*** store_buffer_position = store_buffer()->Start();
6478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object*** store_buffer_top = store_buffer()->Top();
647930ce411529579186181838984710b0b0980857aaricow@chromium.org
6480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object** limit = reinterpret_cast<Object**>(end);
6481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    CheckStoreBuffer(this,
6482c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     current,
6483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     limit,
6484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     &store_buffer_position,
6485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     store_buffer_top,
6486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     &EverythingsAPointer,
6487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     space->top(),
6488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     space->limit());
648930ce411529579186181838984710b0b0980857aaricow@chromium.org  }
649030ce411529579186181838984710b0b0980857aaricow@chromium.org}
649130ce411529579186181838984710b0b0980857aaricow@chromium.org
649230ce411529579186181838984710b0b0980857aaricow@chromium.org
6493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::MapSpaceCheckStoreBuffer() {
6494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MapSpace* space = map_space();
6495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PageIterator pages(space);
649630ce411529579186181838984710b0b0980857aaricow@chromium.org
6497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->SortUniq();
649830ce411529579186181838984710b0b0980857aaricow@chromium.org
6499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (pages.has_next()) {
6500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* page = pages.next();
6501ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Object** current = reinterpret_cast<Object**>(page->area_start());
650230ce411529579186181838984710b0b0980857aaricow@chromium.org
6503ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Address end = page->area_end();
650430ce411529579186181838984710b0b0980857aaricow@chromium.org
6505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object*** store_buffer_position = store_buffer()->Start();
6506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object*** store_buffer_top = store_buffer()->Top();
650730ce411529579186181838984710b0b0980857aaricow@chromium.org
6508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object** limit = reinterpret_cast<Object**>(end);
6509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    CheckStoreBuffer(this,
6510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     current,
6511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     limit,
6512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     &store_buffer_position,
6513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     store_buffer_top,
6514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     &IsAMapPointerAddress,
6515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     space->top(),
6516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     space->limit());
651730ce411529579186181838984710b0b0980857aaricow@chromium.org  }
651843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
651943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
652043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::LargeObjectSpaceCheckStoreBuffer() {
6522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  LargeObjectIterator it(lo_space());
6523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
6524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // We only have code, sequential strings, or fixed arrays in large
6525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // object space, and only fixed arrays can possibly contain pointers to
6526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // the young generation.
6527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (object->IsFixedArray()) {
6528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object*** store_buffer_position = store_buffer()->Start();
6529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object*** store_buffer_top = store_buffer()->Top();
6530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object** current = reinterpret_cast<Object**>(object->address());
6531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object** limit =
6532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          reinterpret_cast<Object**>(object->address() + object->Size());
6533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      CheckStoreBuffer(this,
6534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       current,
6535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       limit,
6536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       &store_buffer_position,
6537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       store_buffer_top,
6538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       &EverythingsAPointer,
6539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       NULL,
6540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       NULL);
654171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org    }
654243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
654343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
6544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
654543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
654643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6547c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) {
6548c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  IterateStrongRoots(v, mode);
6549b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  IterateWeakRoots(v, mode);
6550b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
6551b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
6552b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
6553b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) {
65544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  v->VisitPointer(reinterpret_cast<Object**>(&roots_[kStringTableRootIndex]));
65554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  v->Synchronize(VisitorSynchronization::kStringTable);
6556c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  if (mode != VISIT_ALL_IN_SCAVENGE &&
6557c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      mode != VISIT_ALL_IN_SWEEP_NEWSPACE) {
655813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    // Scavenge collections have special processing for this.
6559ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    external_string_table_.Iterate(v);
656013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
656164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kExternalStringsTable);
656243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
656343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
656443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6565c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
656668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
656764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kStrongRootList);
656843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  v->VisitPointer(BitCast<Object**>(&hidden_string_));
65704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  v->Synchronize(VisitorSynchronization::kInternalizedString);
657143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6572ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->bootstrapper()->Iterate(v);
657364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kBootstrapper);
6574ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->Iterate(v);
657564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kTop);
6576c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  Relocatable::Iterate(v);
657764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kRelocatable);
657865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
657965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
6580ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->debug()->Iterate(v);
65814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (isolate_->deoptimizer_data() != NULL) {
65824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    isolate_->deoptimizer_data()->Iterate(v);
65834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
658465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif
658564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kDebug);
6586ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->compilation_cache()->Iterate(v);
658764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kCompilationCache);
658843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
658943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate over local handles in handle scopes.
6590ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->handle_scope_implementer()->Iterate(v);
6591304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  isolate_->IterateDeferredHandles(v);
659264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kHandleScope);
659343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
659413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Iterate over the builtin code objects and code stubs in the
659513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // heap. Note that it is not necessary to iterate over code objects
659613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // on scavenge collections.
6597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (mode != VISIT_ALL_IN_SCAVENGE) {
6598ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->builtins()->IterateBuiltins(v);
659913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
660064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kBuiltins);
660143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
660243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate over global handles.
6603c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  switch (mode) {
6604c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    case VISIT_ONLY_STRONG:
6605c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      isolate_->global_handles()->IterateStrongRoots(v);
6606c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      break;
6607c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    case VISIT_ALL_IN_SCAVENGE:
6608e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v);
6609c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      break;
6610c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    case VISIT_ALL_IN_SWEEP_NEWSPACE:
6611c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    case VISIT_ALL:
6612c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      isolate_->global_handles()->IterateAllRoots(v);
6613c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      break;
6614c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
661564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kGlobalHandles);
661643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6617594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Iterate over eternal handles.
6618594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (mode == VISIT_ALL_IN_SCAVENGE) {
6619594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    isolate_->eternal_handles()->IterateNewSpaceRoots(v);
6620594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else {
6621594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    isolate_->eternal_handles()->IterateAllRoots(v);
6622594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
6623594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v->Synchronize(VisitorSynchronization::kEternalHandles);
6624594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
662543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate over pointers being held by inactive threads.
6626ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->thread_manager()->Iterate(v);
662764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kThreadManager);
6628b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
6629b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Iterate over the pointers the Serialization/Deserialization code is
6630b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // holding.
6631b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // During garbage collection this keeps the partial snapshot cache alive.
6632b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // During deserialization of the startup snapshot this creates the partial
6633b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // snapshot cache and deserializes the objects it refers to.  During
6634b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // serialization this does nothing, since the partial snapshot cache is
6635b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // empty.  However the next thing we do is create the partial snapshot,
6636b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // filling up the partial snapshot cache with objects it needs as we go.
6637b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  SerializerDeserializer::Iterate(v);
6638b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // We don't do a v->Synchronize call here, because in debug mode that will
6639b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // output a flag to the snapshot.  However at this point the serializer and
6640b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // deserializer are deliberately a little unsynchronized (see above) so the
6641b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // checking of the sync flag in the snapshot would fail.
664243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
664343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
664443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
664543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// TODO(1236194): Since the heap size is configurable on the command line
664643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and through the API, we should gracefully handle the case that the heap
664743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// size is not big enough to fit all the initial objects.
664801fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.orgbool Heap::ConfigureHeap(int max_semispace_size,
6649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                         intptr_t max_old_gen_size,
6650c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                         intptr_t max_executable_size) {
6651f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (HasBeenSetUp()) return false;
665243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6653efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  if (FLAG_stress_compaction) {
6654efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org    // This will cause more frequent GCs when stressing.
6655efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org    max_semispace_size_ = Page::kPageSize;
6656efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  }
6657efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
6658c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (max_semispace_size > 0) {
6659c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (max_semispace_size < Page::kPageSize) {
6660c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      max_semispace_size = Page::kPageSize;
6661c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (FLAG_trace_gc) {
6662657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        PrintPID("Max semispace size cannot be less than %dkbytes\n",
6663657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org                 Page::kPageSize >> 10);
6664c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
6665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
6666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    max_semispace_size_ = max_semispace_size;
6667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
66683811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
66693811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  if (Snapshot::IsEnabled()) {
66703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // If we are using a snapshot we always reserve the default amount
66713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // of memory for each semispace because code in the snapshot has
66723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // write-barrier code that relies on the size and alignment of new
66733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // space.  We therefore cannot use a larger max semispace size
66743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // than the default reserved semispace size.
66753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    if (max_semispace_size_ > reserved_semispace_size_) {
66763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      max_semispace_size_ = reserved_semispace_size_;
6677c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (FLAG_trace_gc) {
6678657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        PrintPID("Max semispace size cannot be more than %dkbytes\n",
6679657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org                 reserved_semispace_size_ >> 10);
6680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
66813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
66823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  } else {
66833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // If we are not using snapshots we reserve space for the actual
66843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // max semispace size.
66853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    reserved_semispace_size_ = max_semispace_size_;
66863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
66873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
66883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  if (max_old_gen_size > 0) max_old_generation_size_ = max_old_gen_size;
668901fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  if (max_executable_size > 0) {
669001fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org    max_executable_size_ = RoundUp(max_executable_size, Page::kPageSize);
669101fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  }
669201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
669301fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // The max executable size must be less than or equal to the max old
669401fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // generation size.
669501fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  if (max_executable_size_ > max_old_generation_size_) {
669601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org    max_executable_size_ = max_old_generation_size_;
669701fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  }
669843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
669943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The new space size must be a power of two to support single-bit testing
670043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for containment.
67013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  max_semispace_size_ = RoundUpToPowerOf2(max_semispace_size_);
67023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  reserved_semispace_size_ = RoundUpToPowerOf2(reserved_semispace_size_);
67033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  initial_semispace_size_ = Min(initial_semispace_size_, max_semispace_size_);
67041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
67051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // The external allocation limit should be below 256 MB on all architectures
67061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // to avoid unnecessary low memory notifications, as that is the threshold
67071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // for some embedders.
67081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_allocation_limit_ = 12 * max_semispace_size_;
67091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(external_allocation_limit_ <= 256 * MB);
671043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The old generation is paged and needs at least one page for each space.
6712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
6713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  max_old_generation_size_ = Max(static_cast<intptr_t>(paged_space_count *
6714c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                       Page::kPageSize),
6715c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                 RoundUp(max_old_generation_size_,
6716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                         Page::kPageSize));
671743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6718ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  configured_ = true;
671943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
672043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
672143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
672243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67237276f14ca716596e0a0d17539516370c1f453847kasper.lundbool Heap::ConfigureHeapDefault() {
6724c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return ConfigureHeap(static_cast<intptr_t>(FLAG_max_new_space_size / 2) * KB,
6725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       static_cast<intptr_t>(FLAG_max_old_space_size) * MB,
6726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       static_cast<intptr_t>(FLAG_max_executable_size) * MB);
67277276f14ca716596e0a0d17539516370c1f453847kasper.lund}
67287276f14ca716596e0a0d17539516370c1f453847kasper.lund
67297276f14ca716596e0a0d17539516370c1f453847kasper.lund
6730c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.orgvoid Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
67310b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  *stats->start_marker = HeapStats::kStartMarker;
67320b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  *stats->end_marker = HeapStats::kEndMarker;
6733f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  *stats->new_space_size = new_space_.SizeAsInt();
6734f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  *stats->new_space_capacity = static_cast<int>(new_space_.Capacity());
67352c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->old_pointer_space_size = old_pointer_space_->SizeOfObjects();
6736ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->old_pointer_space_capacity = old_pointer_space_->Capacity();
67372c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->old_data_space_size = old_data_space_->SizeOfObjects();
6738ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->old_data_space_capacity = old_data_space_->Capacity();
67392c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->code_space_size = code_space_->SizeOfObjects();
6740ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->code_space_capacity = code_space_->Capacity();
67412c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->map_space_size = map_space_->SizeOfObjects();
6742ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->map_space_capacity = map_space_->Capacity();
67432c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->cell_space_size = cell_space_->SizeOfObjects();
6744ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->cell_space_capacity = cell_space_->Capacity();
674541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  *stats->property_cell_space_size = property_cell_space_->SizeOfObjects();
674641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  *stats->property_cell_space_capacity = property_cell_space_->Capacity();
6747ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->lo_space_size = lo_space_->Size();
6748ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->global_handles()->RecordStats(stats);
6749ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  *stats->memory_allocator_size = isolate()->memory_allocator()->Size();
6750c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  *stats->memory_allocator_capacity =
6751ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate()->memory_allocator()->Size() +
6752ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate()->memory_allocator()->Available();
6753ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  *stats->os_error = OS::GetLastError();
6754ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate()->memory_allocator()->Available();
6755c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  if (take_snapshot) {
67567c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    HeapIterator iterator(this);
6757c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    for (HeapObject* obj = iterator.next();
6758c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org         obj != NULL;
6759c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org         obj = iterator.next()) {
6760c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org      InstanceType type = obj->map()->instance_type();
6761c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org      ASSERT(0 <= type && type <= LAST_TYPE);
6762c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org      stats->objects_per_type[type]++;
6763c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org      stats->size_per_type[type] += obj->Size();
6764c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    }
6765c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  }
67666012123a2f016c2ab333c2de98d0debd3966056bager@chromium.org}
67676012123a2f016c2ab333c2de98d0debd3966056bager@chromium.org
67686012123a2f016c2ab333c2de98d0debd3966056bager@chromium.org
6769659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgintptr_t Heap::PromotedSpaceSizeOfObjects() {
6770659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  return old_pointer_space_->SizeOfObjects()
6771659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      + old_data_space_->SizeOfObjects()
6772659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      + code_space_->SizeOfObjects()
6773659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      + map_space_->SizeOfObjects()
6774659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      + cell_space_->SizeOfObjects()
677541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      + property_cell_space_->SizeOfObjects()
6776659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      + lo_space_->SizeOfObjects();
6777659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
6778659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
6779659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
678028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgintptr_t Heap::PromotedExternalMemorySize() {
67817276f14ca716596e0a0d17539516370c1f453847kasper.lund  if (amount_of_external_allocated_memory_
67827276f14ca716596e0a0d17539516370c1f453847kasper.lund      <= amount_of_external_allocated_memory_at_last_global_gc_) return 0;
67837276f14ca716596e0a0d17539516370c1f453847kasper.lund  return amount_of_external_allocated_memory_
67847276f14ca716596e0a0d17539516370c1f453847kasper.lund      - amount_of_external_allocated_memory_at_last_global_gc_;
67857276f14ca716596e0a0d17539516370c1f453847kasper.lund}
67867276f14ca716596e0a0d17539516370c1f453847kasper.lund
67877d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
67887d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgV8_DECLARE_ONCE(initialize_gc_once);
67897d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
67907d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgstatic void InitializeGCOnce() {
67917d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  InitializeScavengingVisitorsTables();
67927d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  NewSpaceScavenger::Initialize();
67937d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  MarkCompactCollector::Initialize();
67947d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org}
67957d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
6796e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
679709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgbool Heap::SetUp() {
6798ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#ifdef DEBUG
6799394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  allocation_timeout_ = FLAG_gc_interval;
6800ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif
6801ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
680243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize heap spaces and initial maps and objects. Whenever something
680343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // goes wrong, just return false. The caller should check the results and
680443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // call Heap::TearDown() to release allocated memory.
680543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
68062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // If the heap is not yet configured (e.g. through the API), configure it.
680743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Configuration is based on the flags new-space-size (really the semispace
680843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // size) and old-space-size if set or the initial values of semispace_size_
680943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // and old_generation_size_ otherwise.
6810ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!configured_) {
68117276f14ca716596e0a0d17539516370c1f453847kasper.lund    if (!ConfigureHeapDefault()) return false;
681243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
681343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68147d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  CallOnce(&initialize_gc_once, &InitializeGCOnce);
6815ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
6816d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  MarkMapPointersAsEncoded(false);
6817d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
6818f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up memory allocator.
6819f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!isolate_->memory_allocator()->SetUp(MaxReserved(), MaxExecutableSize()))
6820ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return false;
6821c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6822f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up new space.
6823f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!new_space_.SetUp(reserved_semispace_size_, max_semispace_size_)) {
68243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    return false;
68253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
682643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6827a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Initialize old pointer space.
68289258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  old_pointer_space_ =
6829ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      new OldSpace(this,
6830ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                   max_old_generation_size_,
6831ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                   OLD_POINTER_SPACE,
6832ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                   NOT_EXECUTABLE);
68339258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (old_pointer_space_ == NULL) return false;
6834f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!old_pointer_space_->SetUp()) return false;
6835a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
6836a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Initialize old data space.
68379258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  old_data_space_ =
6838ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      new OldSpace(this,
6839ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                   max_old_generation_size_,
6840ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                   OLD_DATA_SPACE,
6841ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                   NOT_EXECUTABLE);
68429258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (old_data_space_ == NULL) return false;
6843f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!old_data_space_->SetUp()) return false;
684443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
684543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize the code space, set its maximum capacity to the old
68467276f14ca716596e0a0d17539516370c1f453847kasper.lund  // generation size. It needs executable memory.
6847c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // On 64-bit platform(s), we put all code objects in a 2 GB range of
6848c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // virtual address space, so that they can call each other with near calls.
6849c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  if (code_range_size_ > 0) {
6850f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    if (!isolate_->code_range()->SetUp(code_range_size_)) {
6851c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      return false;
6852c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    }
6853c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
6854c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
68559258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  code_space_ =
6856ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      new OldSpace(this, max_old_generation_size_, CODE_SPACE, EXECUTABLE);
685743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (code_space_ == NULL) return false;
6858f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!code_space_->SetUp()) return false;
685943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
686043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize map space.
686178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  map_space_ = new MapSpace(this, max_old_generation_size_, MAP_SPACE);
686243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (map_space_ == NULL) return false;
6863f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!map_space_->SetUp()) return false;
686443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
686541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Initialize simple cell space.
6866ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  cell_space_ = new CellSpace(this, max_old_generation_size_, CELL_SPACE);
6867defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  if (cell_space_ == NULL) return false;
6868f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!cell_space_->SetUp()) return false;
6869defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
687041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Initialize global property cell space.
687141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  property_cell_space_ = new PropertyCellSpace(this, max_old_generation_size_,
687241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                               PROPERTY_CELL_SPACE);
687341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (property_cell_space_ == NULL) return false;
687441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (!property_cell_space_->SetUp()) return false;
687541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
68769258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // The large object code space may contain code or data.  We set the memory
68779258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // to be non-executable here for safety, but this means we need to enable it
68789258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // explicitly when allocating large code objects.
6879394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  lo_space_ = new LargeObjectSpace(this, max_old_generation_size_, LO_SPACE);
688043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (lo_space_ == NULL) return false;
6881f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!lo_space_->SetUp()) return false;
6882fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
6883f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up the seed that is used to randomize the string hash function.
6884f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  ASSERT(hash_seed() == 0);
6885f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (FLAG_randomize_hashes) {
6886f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    if (FLAG_hash_seed == 0) {
6887f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      set_hash_seed(
6888fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org          Smi::FromInt(V8::RandomPrivate(isolate()) & 0x3fffffff));
6889fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    } else {
6890f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      set_hash_seed(Smi::FromInt(FLAG_hash_seed));
6891fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    }
6892fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  }
6893fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
6894ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
6895ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, IntPtrTEvent("heap-available", Available()));
689643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6897f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  store_buffer()->SetUp();
6898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6899ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (FLAG_parallel_recompilation) relocation_mutex_ = OS::CreateMutex();
6900ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#ifdef DEBUG
6901ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  relocation_mutex_locked_by_optimizer_thread_ = false;
6902ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#endif  // DEBUG
6903ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
690443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
690543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
690643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6907e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
690809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgbool Heap::CreateHeapObjects() {
690909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  // Create initial maps.
691009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (!CreateInitialMaps()) return false;
691109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (!CreateApiObjects()) return false;
691209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
691309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  // Create initial objects
691409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (!CreateInitialObjects()) return false;
691509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
691609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  native_contexts_list_ = undefined_value();
691741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  array_buffers_list_ = undefined_value();
6918ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  allocation_sites_list_ = undefined_value();
691909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  return true;
692009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org}
692109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
692243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6923c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Heap::SetStackLimits() {
6924ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(isolate_ != NULL);
6925ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(isolate_ == isolate());
692618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // On 64 bit machines, pointers are generally out of range of Smis.  We write
692718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // something that looks like an out of range Smi to the GC.
692818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
6929c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Set up the special root array entries containing the stack limits.
6930c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // These are actually addresses, but the tag makes the GC ignore it.
693118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  roots_[kStackLimitRootIndex] =
6932c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      reinterpret_cast<Object*>(
6933ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          (isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag);
6934c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  roots_[kRealStackLimitRootIndex] =
6935c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      reinterpret_cast<Object*>(
6936ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag);
693718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
693818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
693918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
694043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::TearDown() {
6941c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
69421044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  if (FLAG_verify_heap) {
69431044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    Verify();
69441044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
69451044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org#endif
6946c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
69479dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  if (FLAG_print_cumulative_gc_stat) {
6948e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org    PrintF("\n");
69499dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    PrintF("gc_count=%d ", gc_count_);
69509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    PrintF("mark_sweep_count=%d ", ms_count_);
6951c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("max_gc_pause=%.1f ", get_max_gc_pause());
6952c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("total_gc_time=%.1f ", total_gc_time_ms_);
6953c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("min_in_mutator=%.1f ", get_min_in_mutator());
6954f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org    PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ",
6955ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org           get_max_alive_after_gc());
6956c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("total_marking_time=%.1f ", marking_time());
6957c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("total_sweeping_time=%.1f ", sweeping_time());
69589dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    PrintF("\n\n");
69599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
69609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
69611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  TearDownArrayBuffers();
69621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
6963ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->global_handles()->TearDown();
696443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6965ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  external_string_table_.TearDown();
696613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
6967d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  mark_compact_collector()->TearDown();
6968d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
69695a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  new_space_.TearDown();
697043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69719258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (old_pointer_space_ != NULL) {
69729258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    old_pointer_space_->TearDown();
69739258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    delete old_pointer_space_;
69749258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    old_pointer_space_ = NULL;
69759258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
69769258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
69779258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (old_data_space_ != NULL) {
69789258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    old_data_space_->TearDown();
69799258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    delete old_data_space_;
69809258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    old_data_space_ = NULL;
698143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
698243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
698343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (code_space_ != NULL) {
698443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    code_space_->TearDown();
698543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    delete code_space_;
698643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    code_space_ = NULL;
698743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
698843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
698943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (map_space_ != NULL) {
699043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    map_space_->TearDown();
699143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    delete map_space_;
699243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    map_space_ = NULL;
699343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
699443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6995defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  if (cell_space_ != NULL) {
6996defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    cell_space_->TearDown();
6997defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    delete cell_space_;
6998defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    cell_space_ = NULL;
6999defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  }
7000defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
700141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (property_cell_space_ != NULL) {
700241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    property_cell_space_->TearDown();
700341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    delete property_cell_space_;
700441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    property_cell_space_ = NULL;
700541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
700641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
700743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (lo_space_ != NULL) {
700843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    lo_space_->TearDown();
700943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    delete lo_space_;
701043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    lo_space_ = NULL;
701143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
701243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7013c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->TearDown();
7014c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  incremental_marking()->TearDown();
7015c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
7016ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->memory_allocator()->TearDown();
7017ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
7018ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  delete relocation_mutex_;
701943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
702043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
702143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70225d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Heap::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
70235d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  ASSERT(callback != NULL);
70245d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  GCPrologueCallbackPair pair(callback, gc_type);
70255d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  ASSERT(!gc_prologue_callbacks_.Contains(pair));
70265d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  return gc_prologue_callbacks_.Add(pair);
70275d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
70285d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
70295d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
70305d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Heap::RemoveGCPrologueCallback(GCPrologueCallback callback) {
70315d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  ASSERT(callback != NULL);
70325d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
70335d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    if (gc_prologue_callbacks_[i].callback == callback) {
70345d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      gc_prologue_callbacks_.Remove(i);
70355d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return;
70365d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    }
70375d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
70385d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  UNREACHABLE();
70395d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
70405d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
70415d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
70425d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Heap::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
70435d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  ASSERT(callback != NULL);
70445d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  GCEpilogueCallbackPair pair(callback, gc_type);
70455d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  ASSERT(!gc_epilogue_callbacks_.Contains(pair));
70465d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  return gc_epilogue_callbacks_.Add(pair);
70475d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
70485d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
70495d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
70505d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Heap::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
70515d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  ASSERT(callback != NULL);
70525d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
70535d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    if (gc_epilogue_callbacks_[i].callback == callback) {
70545d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      gc_epilogue_callbacks_.Remove(i);
70555d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return;
70565d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    }
70575d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
70585d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  UNREACHABLE();
70595d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
70605d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
70615d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
706243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
706343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
706443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass PrintHandleVisitor: public ObjectVisitor {
706543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
706643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void VisitPointers(Object** start, Object** end) {
706743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (Object** p = start; p < end; p++)
7068f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org      PrintF("  handle %p to %p\n",
7069f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org             reinterpret_cast<void*>(p),
7070f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org             reinterpret_cast<void*>(*p));
707143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
707243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
707343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7074e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
707543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::PrintHandles() {
707643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Handles:\n");
707743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintHandleVisitor v;
7078ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->handle_scope_implementer()->Iterate(&v);
707943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
708043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
708143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
708243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
708343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70849258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgSpace* AllSpaces::next() {
70859258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  switch (counter_++) {
70869258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case NEW_SPACE:
70877c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->new_space();
70889258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
70897c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_pointer_space();
70909258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
70917c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_data_space();
70929258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case CODE_SPACE:
70937c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->code_space();
70949258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case MAP_SPACE:
70957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->map_space();
7096defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    case CELL_SPACE:
70977c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->cell_space();
709841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_SPACE:
709941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      return heap_->property_cell_space();
71009258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case LO_SPACE:
71017c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->lo_space();
71029258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    default:
71039258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return NULL;
71049258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
71059258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
71069258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
71079258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
71089258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgPagedSpace* PagedSpaces::next() {
71099258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  switch (counter_++) {
71109258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
71117c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_pointer_space();
71129258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
71137c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_data_space();
71149258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case CODE_SPACE:
71157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->code_space();
71169258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case MAP_SPACE:
71177c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->map_space();
7118defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    case CELL_SPACE:
71197c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->cell_space();
712041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_SPACE:
712141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      return heap_->property_cell_space();
71229258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    default:
71239258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return NULL;
71249258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
71259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
71269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
71279258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
71289258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
71299258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgOldSpace* OldSpaces::next() {
71309258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  switch (counter_++) {
71319258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
71327c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_pointer_space();
71339258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
71347c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_data_space();
71359258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case CODE_SPACE:
71367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->code_space();
71379258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    default:
71389258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return NULL;
71399258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
71409258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
71419258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
71429258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
71437c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgSpaceIterator::SpaceIterator(Heap* heap)
71447c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    : heap_(heap),
71457c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      current_space_(FIRST_SPACE),
71464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      iterator_(NULL),
71474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      size_func_(NULL) {
71484a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
71494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
71504a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
71517c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgSpaceIterator::SpaceIterator(Heap* heap, HeapObjectCallback size_func)
71527c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    : heap_(heap),
71537c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      current_space_(FIRST_SPACE),
71544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      iterator_(NULL),
71554a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      size_func_(size_func) {
71567276f14ca716596e0a0d17539516370c1f453847kasper.lund}
71577276f14ca716596e0a0d17539516370c1f453847kasper.lund
71587276f14ca716596e0a0d17539516370c1f453847kasper.lund
71597276f14ca716596e0a0d17539516370c1f453847kasper.lundSpaceIterator::~SpaceIterator() {
71607276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Delete active iterator if any.
71617276f14ca716596e0a0d17539516370c1f453847kasper.lund  delete iterator_;
71627276f14ca716596e0a0d17539516370c1f453847kasper.lund}
71637276f14ca716596e0a0d17539516370c1f453847kasper.lund
71647276f14ca716596e0a0d17539516370c1f453847kasper.lund
71657276f14ca716596e0a0d17539516370c1f453847kasper.lundbool SpaceIterator::has_next() {
71667276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Iterate until no more spaces.
71677276f14ca716596e0a0d17539516370c1f453847kasper.lund  return current_space_ != LAST_SPACE;
71687276f14ca716596e0a0d17539516370c1f453847kasper.lund}
71697276f14ca716596e0a0d17539516370c1f453847kasper.lund
71707276f14ca716596e0a0d17539516370c1f453847kasper.lund
71717276f14ca716596e0a0d17539516370c1f453847kasper.lundObjectIterator* SpaceIterator::next() {
71727276f14ca716596e0a0d17539516370c1f453847kasper.lund  if (iterator_ != NULL) {
71737276f14ca716596e0a0d17539516370c1f453847kasper.lund    delete iterator_;
71747276f14ca716596e0a0d17539516370c1f453847kasper.lund    iterator_ = NULL;
71757276f14ca716596e0a0d17539516370c1f453847kasper.lund    // Move to the next space
71767276f14ca716596e0a0d17539516370c1f453847kasper.lund    current_space_++;
71777276f14ca716596e0a0d17539516370c1f453847kasper.lund    if (current_space_ > LAST_SPACE) {
71787276f14ca716596e0a0d17539516370c1f453847kasper.lund      return NULL;
71797276f14ca716596e0a0d17539516370c1f453847kasper.lund    }
71807276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
71817276f14ca716596e0a0d17539516370c1f453847kasper.lund
71827276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Return iterator for the new current space.
71837276f14ca716596e0a0d17539516370c1f453847kasper.lund  return CreateIterator();
71847276f14ca716596e0a0d17539516370c1f453847kasper.lund}
71857276f14ca716596e0a0d17539516370c1f453847kasper.lund
71867276f14ca716596e0a0d17539516370c1f453847kasper.lund
71877276f14ca716596e0a0d17539516370c1f453847kasper.lund// Create an iterator for the space to iterate.
71887276f14ca716596e0a0d17539516370c1f453847kasper.lundObjectIterator* SpaceIterator::CreateIterator() {
71897276f14ca716596e0a0d17539516370c1f453847kasper.lund  ASSERT(iterator_ == NULL);
71907276f14ca716596e0a0d17539516370c1f453847kasper.lund
71917276f14ca716596e0a0d17539516370c1f453847kasper.lund  switch (current_space_) {
71927276f14ca716596e0a0d17539516370c1f453847kasper.lund    case NEW_SPACE:
71937c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new SemiSpaceIterator(heap_->new_space(), size_func_);
71947276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
71959258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
71967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ =
71977c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org          new HeapObjectIterator(heap_->old_pointer_space(), size_func_);
71989258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      break;
71999258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
72007c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new HeapObjectIterator(heap_->old_data_space(), size_func_);
72017276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
72027276f14ca716596e0a0d17539516370c1f453847kasper.lund    case CODE_SPACE:
72037c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new HeapObjectIterator(heap_->code_space(), size_func_);
72047276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
72057276f14ca716596e0a0d17539516370c1f453847kasper.lund    case MAP_SPACE:
72067c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new HeapObjectIterator(heap_->map_space(), size_func_);
72077276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
7208defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    case CELL_SPACE:
72097c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new HeapObjectIterator(heap_->cell_space(), size_func_);
7210defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      break;
721141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_SPACE:
721241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      iterator_ = new HeapObjectIterator(heap_->property_cell_space(),
721341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                         size_func_);
721441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      break;
72157276f14ca716596e0a0d17539516370c1f453847kasper.lund    case LO_SPACE:
72167c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new LargeObjectIterator(heap_->lo_space(), size_func_);
72177276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
72187276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
72197276f14ca716596e0a0d17539516370c1f453847kasper.lund
72207276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Return the newly allocated iterator;
72217276f14ca716596e0a0d17539516370c1f453847kasper.lund  ASSERT(iterator_ != NULL);
72227276f14ca716596e0a0d17539516370c1f453847kasper.lund  return iterator_;
72237276f14ca716596e0a0d17539516370c1f453847kasper.lund}
72247276f14ca716596e0a0d17539516370c1f453847kasper.lund
72257276f14ca716596e0a0d17539516370c1f453847kasper.lund
7226023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgclass HeapObjectsFilter {
7227023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org public:
7228023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  virtual ~HeapObjectsFilter() {}
7229023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  virtual bool SkipObject(HeapObject* object) = 0;
7230023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org};
7231023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
7232023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
7233023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgclass UnreachableObjectsFilter : public HeapObjectsFilter {
7234023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org public:
7235023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  UnreachableObjectsFilter() {
7236394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MarkReachableObjects();
7237394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
7238394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
7239394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ~UnreachableObjectsFilter() {
7240394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Isolate::Current()->heap()->mark_compact_collector()->ClearMarkbits();
7241023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  }
7242023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
7243023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  bool SkipObject(HeapObject* object) {
7244394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(object);
7245394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return !mark_bit.Get();
7246023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  }
7247023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
7248023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org private:
7249394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  class MarkingVisitor : public ObjectVisitor {
7250023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org   public:
7251394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MarkingVisitor() : marking_stack_(10) {}
7252023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
7253023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    void VisitPointers(Object** start, Object** end) {
7254023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      for (Object** p = start; p < end; p++) {
7255023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org        if (!(*p)->IsHeapObject()) continue;
7256023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org        HeapObject* obj = HeapObject::cast(*p);
7257394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        MarkBit mark_bit = Marking::MarkBitFrom(obj);
7258394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        if (!mark_bit.Get()) {
7259394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          mark_bit.Set();
7260394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          marking_stack_.Add(obj);
7261023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org        }
7262023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      }
7263023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    }
7264023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
7265394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    void TransitiveClosure() {
7266394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      while (!marking_stack_.is_empty()) {
7267394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        HeapObject* obj = marking_stack_.RemoveLast();
7268394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        obj->Iterate(this);
7269394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
7270023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    }
7271023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
7272023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org   private:
7273394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    List<HeapObject*> marking_stack_;
7274023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  };
7275023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
7276394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  void MarkReachableObjects() {
7277394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Heap* heap = Isolate::Current()->heap();
7278394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MarkingVisitor visitor;
7279394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    heap->IterateRoots(&visitor, VISIT_ALL);
7280394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    visitor.TransitiveClosure();
7281023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  }
7282023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
728379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation_;
7284023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org};
7285023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
7286023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
72877c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgHeapIterator::HeapIterator(Heap* heap)
72887c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    : heap_(heap),
72897c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      filtering_(HeapIterator::kNoFiltering),
72904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      filter_(NULL) {
72914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  Init();
72924a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
72934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
72944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
72957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgHeapIterator::HeapIterator(Heap* heap,
72967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                           HeapIterator::HeapObjectsFiltering filtering)
72977c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    : heap_(heap),
72987c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      filtering_(filtering),
72994a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      filter_(NULL) {
730043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Init();
730143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
730243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
730343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
730443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHeapIterator::~HeapIterator() {
730543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Shutdown();
730643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
730743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
730843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
730943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid HeapIterator::Init() {
731043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Start the iteration.
73117c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  space_iterator_ = new SpaceIterator(heap_);
7312023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  switch (filtering_) {
7313023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    case kFilterUnreachable:
7314023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      filter_ = new UnreachableObjectsFilter;
7315023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      break;
7316023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    default:
7317023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      break;
73184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
731943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  object_iterator_ = space_iterator_->next();
732043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
732143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
732243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
732343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid HeapIterator::Shutdown() {
73244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#ifdef DEBUG
7325023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  // Assert that in filtering mode we have iterated through all
73264a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // objects. Otherwise, heap will be left in an inconsistent state.
7327023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  if (filtering_ != kNoFiltering) {
73284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    ASSERT(object_iterator_ == NULL);
73294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
73304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#endif
733143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure the last iterator is deallocated.
733243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  delete space_iterator_;
733343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  space_iterator_ = NULL;
733443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  object_iterator_ = NULL;
73354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  delete filter_;
73364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  filter_ = NULL;
733743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
733843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
733943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7340b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgHeapObject* HeapIterator::next() {
73414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (filter_ == NULL) return NextObject();
73424a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
73434a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  HeapObject* obj = NextObject();
7344023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  while (obj != NULL && filter_->SkipObject(obj)) obj = NextObject();
73454a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return obj;
73464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
73474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
73484a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
73494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comHeapObject* HeapIterator::NextObject() {
735043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // No iterator means we are done.
7351b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (object_iterator_ == NULL) return NULL;
735243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7353b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (HeapObject* obj = object_iterator_->next_object()) {
735443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If the current iterator has more objects we are fine.
7355b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return obj;
735643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
735743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Go though the spaces looking for one that has objects.
735843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (space_iterator_->has_next()) {
735943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      object_iterator_ = space_iterator_->next();
7360b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      if (HeapObject* obj = object_iterator_->next_object()) {
7361b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org        return obj;
736243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
736343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
736443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
736543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Done with the last space.
736643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  object_iterator_ = NULL;
7367b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return NULL;
736843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
736943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
737043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
737143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid HeapIterator::reset() {
737243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Restart the iterator.
737343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Shutdown();
737443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Init();
737543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
737643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
737743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
737846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org#ifdef DEBUG
73793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
7380ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgObject* const PathTracer::kAnyGlobalObject = NULL;
738143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgclass PathTracer::MarkVisitor: public ObjectVisitor {
73833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public:
73843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  explicit MarkVisitor(PathTracer* tracer) : tracer_(tracer) {}
73853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void VisitPointers(Object** start, Object** end) {
73863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Scan all HeapObject pointers in [start, end)
73873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    for (Object** p = start; !tracer_->found() && (p < end); p++) {
73883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      if ((*p)->IsHeapObject())
73893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        tracer_->MarkRecursively(p, this);
73903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
73913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
739243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private:
73943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  PathTracer* tracer_;
73953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org};
739643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
739743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgclass PathTracer::UnmarkVisitor: public ObjectVisitor {
739943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
74003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  explicit UnmarkVisitor(PathTracer* tracer) : tracer_(tracer) {}
740143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void VisitPointers(Object** start, Object** end) {
74023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Scan all HeapObject pointers in [start, end)
740343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (Object** p = start; p < end; p++) {
740443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if ((*p)->IsHeapObject())
74053a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        tracer_->UnmarkRecursively(p, this);
740643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
740743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
74083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
74093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private:
74103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  PathTracer* tracer_;
741143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
741243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
741343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::VisitPointers(Object** start, Object** end) {
74153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  bool done = ((what_to_find_ == FIND_FIRST) && found_target_);
74163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Visit all HeapObject pointers in [start, end)
74173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  for (Object** p = start; !done && (p < end); p++) {
74183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if ((*p)->IsHeapObject()) {
74193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      TracePathFrom(p);
74203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      done = ((what_to_find_ == FIND_FIRST) && found_target_);
74213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
74223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
74233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
74243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
74253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
74263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::Reset() {
74273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  found_target_ = false;
74283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  object_stack_.Clear();
74293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
74303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
74313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
74323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::TracePathFrom(Object** root) {
74333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT((search_target_ == kAnyGlobalObject) ||
74343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org         search_target_->IsHeapObject());
74353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  found_target_in_trace_ = false;
74365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Reset();
74373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
74383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  MarkVisitor mark_visitor(this);
74393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  MarkRecursively(root, &mark_visitor);
74403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
74413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  UnmarkVisitor unmark_visitor(this);
74423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  UnmarkRecursively(root, &unmark_visitor);
74433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
74443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ProcessResults();
74453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
74463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
74473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
744846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgstatic bool SafeIsNativeContext(HeapObject* obj) {
744946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return obj->map() == obj->GetHeap()->raw_unchecked_native_context_map();
7450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
7451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
7452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
74533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) {
745443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!(*p)->IsHeapObject()) return;
745543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
745643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapObject* obj = HeapObject::cast(*p);
745743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
745843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* map = obj->map();
745943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
746043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!map->IsHeapObject()) return;  // visited before
746143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if (found_target_in_trace_) return;  // stop if target found
74633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  object_stack_.Add(obj);
74643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if (((search_target_ == kAnyGlobalObject) && obj->IsJSGlobalObject()) ||
74653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      (obj == search_target_)) {
74663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    found_target_in_trace_ = true;
74673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    found_target_ = true;
746843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
746943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
747043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
747146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  bool is_native_context = SafeIsNativeContext(obj);
74723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
747343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // not visited yet
747443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map));
747543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
747643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address map_addr = map_p->address();
747743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
747864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  obj->set_map_no_write_barrier(reinterpret_cast<Map*>(map_addr + kMarkTag));
747943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Scan the object body.
748146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (is_native_context && (visit_mode_ == VISIT_ONLY_STRONG)) {
74823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // This is specialized to scan Context's properly.
74832ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    Object** start = reinterpret_cast<Object**>(obj->address() +
74842ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org                                                Context::kHeaderSize);
74852ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    Object** end = reinterpret_cast<Object**>(obj->address() +
74863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        Context::kHeaderSize + Context::FIRST_WEAK_SLOT * kPointerSize);
74872ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    mark_visitor->VisitPointers(start, end);
74883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
74893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    obj->IterateBody(map_p->instance_type(),
74903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     obj->SizeFromMap(map_p),
74913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     mark_visitor);
74923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
749343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Scan the map after the body because the body is a lot more interesting
74953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // when doing leak detection.
74963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  MarkRecursively(&map, mark_visitor);
749743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if (!found_target_in_trace_)  // don't pop if found the target
74993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    object_stack_.RemoveLast();
750043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
750143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
750243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::UnmarkRecursively(Object** p, UnmarkVisitor* unmark_visitor) {
750443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!(*p)->IsHeapObject()) return;
750543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
750643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapObject* obj = HeapObject::cast(*p);
750743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
750843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* map = obj->map();
750943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
751043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (map->IsHeapObject()) return;  // unmarked already
751143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
751243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address map_addr = reinterpret_cast<Address>(map);
751343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
751443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map_addr -= kMarkTag;
751543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
751643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT_TAG_ALIGNED(map_addr);
751743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
751843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapObject* map_p = HeapObject::FromAddress(map_addr);
751943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
752064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  obj->set_map_no_write_barrier(reinterpret_cast<Map*>(map_p));
752143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  UnmarkRecursively(reinterpret_cast<Object**>(&map_p), unmark_visitor);
752343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
752443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  obj->IterateBody(Map::cast(map_p)->instance_type(),
752543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   obj->SizeFromMap(Map::cast(map_p)),
75263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                   unmark_visitor);
752743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
752843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
752943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::ProcessResults() {
75313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if (found_target_) {
753243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("=====================================\n");
753343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("====        Path to object       ====\n");
753443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("=====================================\n\n");
753543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    ASSERT(!object_stack_.is_empty());
75373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    for (int i = 0; i < object_stack_.length(); i++) {
753843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (i > 0) PrintF("\n     |\n     |\n     V\n\n");
75393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      Object* obj = object_stack_[i];
754043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      obj->Print();
754143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
754243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("=====================================\n");
754343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
754443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
754543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
754643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7547ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org// Triggers a depth-first traversal of reachable objects from one
7548ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org// given root object and finds a path to a specific heap object and
7549ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org// prints it.
7550ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.orgvoid Heap::TracePathToObjectFrom(Object* target, Object* root) {
7551ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL);
7552ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  tracer.VisitPointer(&root);
7553ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org}
7554ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
7555ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
755643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Triggers a depth-first traversal of reachable objects from roots
755743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and finds a path to a specific heap object and prints it.
755813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Heap::TracePathToObject(Object* target) {
75593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL);
75603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  IterateRoots(&tracer, VISIT_ONLY_STRONG);
756143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
756243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
756343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
756443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Triggers a depth-first traversal of reachable objects from roots
756543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and finds a path to any global object and prints it. Useful for
756643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// determining the source for leaks of global objects.
756743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::TracePathToGlobal() {
75683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  PathTracer tracer(PathTracer::kAnyGlobalObject,
75693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                    PathTracer::FIND_ALL,
75703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                    VISIT_ALL);
75713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  IterateRoots(&tracer, VISIT_ONLY_STRONG);
757243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
757343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
757443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
757543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75767c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgstatic intptr_t CountTotalHolesSize(Heap* heap) {
7577f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  intptr_t holes_size = 0;
75787c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  OldSpaces spaces(heap);
75799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  for (OldSpace* space = spaces.next();
75809dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com       space != NULL;
75819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com       space = spaces.next()) {
7582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    holes_size += space->Waste() + space->Available();
75839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
75849dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return holes_size;
75859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
75869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
75879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7588994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgGCTracer::GCTracer(Heap* heap,
7589994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                   const char* gc_reason,
7590994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                   const char* collector_reason)
75917276f14ca716596e0a0d17539516370c1f453847kasper.lund    : start_time_(0.0),
75921145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      start_object_size_(0),
75931145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      start_memory_size_(0),
75947276f14ca716596e0a0d17539516370c1f453847kasper.lund      gc_count_(0),
75957276f14ca716596e0a0d17539516370c1f453847kasper.lund      full_gc_count_(0),
75969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com      allocated_since_last_gc_(0),
75979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com      spent_in_mutator_(0),
7598ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      promoted_objects_size_(0),
7599cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org      nodes_died_in_new_space_(0),
7600cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org      nodes_copied_in_new_space_(0),
7601cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org      nodes_promoted_(0),
7602994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      heap_(heap),
7603994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      gc_reason_(gc_reason),
7604994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      collector_reason_(collector_reason) {
76059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
76067276f14ca716596e0a0d17539516370c1f453847kasper.lund  start_time_ = OS::TimeCurrentMillis();
76071145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  start_object_size_ = heap_->SizeOfObjects();
76081145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  start_memory_size_ = heap_->isolate()->memory_allocator()->Size();
76099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
76109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  for (int i = 0; i < Scope::kNumberOfScopes; i++) {
76119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    scopes_[i] = 0;
76129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
76139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
76147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  in_free_list_or_wasted_before_gc_ = CountTotalHolesSize(heap);
76159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7616ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  allocated_since_last_gc_ =
7617ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      heap_->SizeOfObjects() - heap_->alive_after_last_gc_;
76189dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7619ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (heap_->last_gc_end_timestamp_ > 0) {
7620ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    spent_in_mutator_ = Max(start_time_ - heap_->last_gc_end_timestamp_, 0.0);
76219dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
7622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
7623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  steps_count_ = heap_->incremental_marking()->steps_count();
7624c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  steps_took_ = heap_->incremental_marking()->steps_took();
7625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  longest_step_ = heap_->incremental_marking()->longest_step();
7626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  steps_count_since_last_gc_ =
7627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      heap_->incremental_marking()->steps_count_since_last_gc();
7628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  steps_took_since_last_gc_ =
7629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      heap_->incremental_marking()->steps_took_since_last_gc();
76307276f14ca716596e0a0d17539516370c1f453847kasper.lund}
76317276f14ca716596e0a0d17539516370c1f453847kasper.lund
76327276f14ca716596e0a0d17539516370c1f453847kasper.lund
76337276f14ca716596e0a0d17539516370c1f453847kasper.lundGCTracer::~GCTracer() {
76347276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Printf ONE line iff flag is set.
76359dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
76369dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7637ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool first_gc = (heap_->last_gc_end_timestamp_ == 0);
76389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7639ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  heap_->alive_after_last_gc_ = heap_->SizeOfObjects();
7640ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  heap_->last_gc_end_timestamp_ = OS::TimeCurrentMillis();
76419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7642c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  double time = heap_->last_gc_end_timestamp_ - start_time_;
76439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
76449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // Update cumulative GC statistics if required.
76459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  if (FLAG_print_cumulative_gc_stat) {
7646471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    heap_->total_gc_time_ms_ += time;
7647ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    heap_->max_gc_pause_ = Max(heap_->max_gc_pause_, time);
7648ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    heap_->max_alive_after_gc_ = Max(heap_->max_alive_after_gc_,
7649ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                     heap_->alive_after_last_gc_);
76509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    if (!first_gc) {
7651ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      heap_->min_in_mutator_ = Min(heap_->min_in_mutator_,
7652c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org                                   spent_in_mutator_);
76539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    }
7654471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  } else if (FLAG_trace_gc_verbose) {
7655471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    heap_->total_gc_time_ms_ += time;
76569dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
76579dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7658471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  if (collector_ == SCAVENGER && FLAG_trace_gc_ignore_scavenger) return;
7659471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
7660e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  heap_->AddMarkingTime(scopes_[Scope::MC_MARK]);
7661e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
7662e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  if (FLAG_print_cumulative_gc_stat && !FLAG_trace_gc) return;
7663657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  PrintPID("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
7664994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
76659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  if (!FLAG_trace_gc_nvp) {
76669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    int external_time = static_cast<int>(scopes_[Scope::EXTERNAL]);
76679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
76681145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org    double end_memory_size_mb =
76691145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org        static_cast<double>(heap_->isolate()->memory_allocator()->Size()) / MB;
76701145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org
76711145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org    PrintF("%s %.1f (%.1f) -> %.1f (%.1f) MB, ",
76729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com           CollectorString(),
76731145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org           static_cast<double>(start_object_size_) / MB,
76741145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org           static_cast<double>(start_memory_size_) / MB,
76751145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org           SizeOfHeapObjects(),
76761145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org           end_memory_size_mb);
76779dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
76789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    if (external_time > 0) PrintF("%d / ", external_time);
7679c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("%.1f ms", time);
7680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (steps_count_ > 0) {
7681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (collector_ == SCAVENGER) {
7682c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        PrintF(" (+ %.1f ms in %d steps since last GC)",
7683c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org               steps_took_since_last_gc_,
7684c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com               steps_count_since_last_gc_);
7685c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else {
7686c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        PrintF(" (+ %.1f ms in %d steps since start of marking, "
7687c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org                   "biggest step %.1f ms)",
7688c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org               steps_took_,
7689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com               steps_count_,
7690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com               longest_step_);
7691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
7692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
7693994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
7694994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    if (gc_reason_ != NULL) {
7695994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      PrintF(" [%s]", gc_reason_);
7696994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    }
7697994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
7698994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    if (collector_reason_ != NULL) {
7699994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      PrintF(" [%s]", collector_reason_);
7700994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    }
7701994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
7702c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    PrintF(".\n");
77039dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  } else {
7704c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("pause=%.1f ", time);
7705c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("mutator=%.1f ", spent_in_mutator_);
77069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    PrintF("gc=");
77079dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    switch (collector_) {
77089dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com      case SCAVENGER:
77099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com        PrintF("s");
77109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com        break;
77119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com      case MARK_COMPACTOR:
7712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        PrintF("ms");
77139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com        break;
77149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com      default:
77159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com        UNREACHABLE();
77169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    }
77179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    PrintF(" ");
77189dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7719c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("external=%.1f ", scopes_[Scope::EXTERNAL]);
7720c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("mark=%.1f ", scopes_[Scope::MC_MARK]);
7721c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("sweep=%.1f ", scopes_[Scope::MC_SWEEP]);
7722c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("sweepns=%.1f ", scopes_[Scope::MC_SWEEP_NEWSPACE]);
7723c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("evacuate=%.1f ", scopes_[Scope::MC_EVACUATE_PAGES]);
7724c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("new_new=%.1f ", scopes_[Scope::MC_UPDATE_NEW_TO_NEW_POINTERS]);
7725c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("root_new=%.1f ", scopes_[Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS]);
7726c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("old_new=%.1f ", scopes_[Scope::MC_UPDATE_OLD_TO_NEW_POINTERS]);
7727c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("compaction_ptrs=%.1f ",
7728c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        scopes_[Scope::MC_UPDATE_POINTERS_TO_EVACUATED]);
7729c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("intracompaction_ptrs=%.1f ",
7730c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        scopes_[Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED]);
7731c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("misc_compaction=%.1f ", scopes_[Scope::MC_UPDATE_MISC_POINTERS]);
7732ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    PrintF("weakcollection_process=%.1f ",
7733ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        scopes_[Scope::MC_WEAKCOLLECTION_PROCESS]);
7734ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    PrintF("weakcollection_clear=%.1f ",
7735ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        scopes_[Scope::MC_WEAKCOLLECTION_CLEAR]);
77369dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
77371145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org    PrintF("total_size_before=%" V8_PTR_PREFIX "d ", start_object_size_);
7738ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    PrintF("total_size_after=%" V8_PTR_PREFIX "d ", heap_->SizeOfObjects());
7739f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org    PrintF("holes_size_before=%" V8_PTR_PREFIX "d ",
7740f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org           in_free_list_or_wasted_before_gc_);
77417c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", CountTotalHolesSize(heap_));
77429dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7743f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org    PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc_);
7744f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org    PrintF("promoted=%" V8_PTR_PREFIX "d ", promoted_objects_size_);
7745cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org    PrintF("nodes_died_in_new=%d ", nodes_died_in_new_space_);
7746cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org    PrintF("nodes_copied_in_new=%d ", nodes_copied_in_new_space_);
7747cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org    PrintF("nodes_promoted=%d ", nodes_promoted_);
77489dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7749c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (collector_ == SCAVENGER) {
7750c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      PrintF("stepscount=%d ", steps_count_since_last_gc_);
7751c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      PrintF("stepstook=%.1f ", steps_took_since_last_gc_);
7752c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
7753c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      PrintF("stepscount=%d ", steps_count_);
7754c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      PrintF("stepstook=%.1f ", steps_took_);
7755c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      PrintF("longeststep=%.1f ", longest_step_);
7756c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
7757c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
77589dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    PrintF("\n");
77599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
7760e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
7761ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  heap_->PrintShortHeapStatistics();
77627276f14ca716596e0a0d17539516370c1f453847kasper.lund}
77637276f14ca716596e0a0d17539516370c1f453847kasper.lund
77647276f14ca716596e0a0d17539516370c1f453847kasper.lund
77657276f14ca716596e0a0d17539516370c1f453847kasper.lundconst char* GCTracer::CollectorString() {
77667276f14ca716596e0a0d17539516370c1f453847kasper.lund  switch (collector_) {
77677276f14ca716596e0a0d17539516370c1f453847kasper.lund    case SCAVENGER:
77687276f14ca716596e0a0d17539516370c1f453847kasper.lund      return "Scavenge";
77697276f14ca716596e0a0d17539516370c1f453847kasper.lund    case MARK_COMPACTOR:
7770c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return "Mark-sweep";
77717276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
77727276f14ca716596e0a0d17539516370c1f453847kasper.lund  return "Unknown GC";
77737276f14ca716596e0a0d17539516370c1f453847kasper.lund}
77747276f14ca716596e0a0d17539516370c1f453847kasper.lund
77757276f14ca716596e0a0d17539516370c1f453847kasper.lund
7776750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgint KeyedLookupCache::Hash(Map* map, Name* name) {
77775aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Uses only lower 32 bits if pointers are larger.
77785aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  uintptr_t addr_hash =
777913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)) >> kMapHashShift;
7780b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask);
77815aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
77825aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
77835aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
7784750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgint KeyedLookupCache::Lookup(Map* map, Name* name) {
778505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  int index = (Hash(map, name) & kHashMask);
7786659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  for (int i = 0; i < kEntriesPerBucket; i++) {
7787659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Key& key = keys_[index + i];
7788659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if ((key.map == map) && key.name->Equals(name)) {
7789659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      return field_offsets_[index + i];
7790659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
779105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
7792ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return kNotFound;
77935aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
77945aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
77955aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
7796750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid KeyedLookupCache::Update(Map* map, Name* name, int field_offset) {
7797750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (!name->IsUniqueName()) {
7798750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    String* internalized_string;
7799750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (!HEAP->InternalizeStringIfExists(
7800750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org            String::cast(name), &internalized_string)) {
7801750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      return;
7802659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
7803750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    name = internalized_string;
7804750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
7805f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // This cache is cleared only between mark compact passes, so we expect the
7806f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // cache to only contain old space names.
7807f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(!HEAP->InNewSpace(name));
7808659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
7809750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  int index = (Hash(map, name) & kHashMask);
7810750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // After a GC there will be free slots, so we use them in order (this may
7811750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // help to get the most frequently used one in position 0).
7812750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  for (int i = 0; i< kEntriesPerBucket; i++) {
7813659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Key& key = keys_[index];
7814750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Object* free_entry_indicator = NULL;
7815750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (key.map == free_entry_indicator) {
7816750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      key.map = map;
7817750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      key.name = name;
7818750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      field_offsets_[index + i] = field_offset;
7819750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      return;
7820750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
78215aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
7822750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // No free entry found in this bucket, so we move them all down one and
7823750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // put the new entry at position zero.
7824750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  for (int i = kEntriesPerBucket - 1; i > 0; i--) {
7825750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Key& key = keys_[index + i];
7826750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Key& key2 = keys_[index + i - 1];
7827750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    key = key2;
7828750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    field_offsets_[index + i] = field_offsets_[index + i - 1];
7829750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
7830750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
7831750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Write the new first entry.
7832750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Key& key = keys_[index];
7833750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  key.map = map;
7834750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  key.name = name;
7835750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  field_offsets_[index] = field_offset;
78365aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
78375aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
78385aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
78395aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid KeyedLookupCache::Clear() {
78405aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  for (int index = 0; index < kLength; index++) keys_[index].map = NULL;
78415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
78425aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
78435aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
78445aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid DescriptorLookupCache::Clear() {
784506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  for (int index = 0; index < kLength; index++) keys_[index].source = NULL;
78465aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
78475aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
78485aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
78495a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org#ifdef DEBUG
78504a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid Heap::GarbageCollectionGreedyCheck() {
78515a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  ASSERT(FLAG_gc_greedy);
7852ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (isolate_->bootstrapper()->IsActive()) return;
78534a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  if (disallow_allocation_failure()) return;
78544a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  CollectGarbage(NEW_SPACE);
78555a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
78565a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org#endif
78575a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
785818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
7859ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgTranscendentalCache::SubCache::SubCache(Type t)
7860ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  : type_(t),
7861ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_(Isolate::Current()) {
786218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  uint32_t in0 = 0xffffffffu;  // Bit-pattern for a NaN that isn't
786318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  uint32_t in1 = 0xffffffffu;  // generated by the FPU.
786418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  for (int i = 0; i < kCacheSize; i++) {
786518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    elements_[i].in[0] = in0;
786618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    elements_[i].in[1] = in1;
786718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    elements_[i].output = NULL;
786818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
786918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
787018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
787118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
787218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid TranscendentalCache::Clear() {
787318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  for (int i = 0; i < kNumberOfCaches; i++) {
787418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    if (caches_[i] != NULL) {
787518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org      delete caches_[i];
787618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org      caches_[i] = NULL;
787718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    }
787818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
787918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
788018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
788118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
788213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid ExternalStringTable::CleanUp() {
788313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  int last = 0;
788413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  for (int i = 0; i < new_space_strings_.length(); ++i) {
788572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (new_space_strings_[i] == heap_->the_hole_value()) {
7886c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      continue;
7887c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
7888ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (heap_->InNewSpace(new_space_strings_[i])) {
788913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      new_space_strings_[last++] = new_space_strings_[i];
789013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    } else {
789113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      old_space_strings_.Add(new_space_strings_[i]);
789213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    }
789313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
789413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  new_space_strings_.Rewind(last);
789546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  new_space_strings_.Trim();
789646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
789713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  last = 0;
789813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  for (int i = 0; i < old_space_strings_.length(); ++i) {
789972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (old_space_strings_[i] == heap_->the_hole_value()) {
7900c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      continue;
7901c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
7902ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
790313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    old_space_strings_[last++] = old_space_strings_[i];
790413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
790513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  old_space_strings_.Rewind(last);
790646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  old_space_strings_.Trim();
7907c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
7908394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
7909394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Verify();
7910394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
7911c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
791213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
791313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
791413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
791513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid ExternalStringTable::TearDown() {
791613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  new_space_strings_.Free();
791713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  old_space_strings_.Free();
791813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
791913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
792013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
7921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) {
7922c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  chunk->set_next_chunk(chunks_queued_for_free_);
7923c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  chunks_queued_for_free_ = chunk;
7924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
7925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
7926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
7927c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::FreeQueuedChunks() {
7928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (chunks_queued_for_free_ == NULL) return;
7929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MemoryChunk* next;
7930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MemoryChunk* chunk;
7931c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) {
7932c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    next = chunk->next_chunk();
7933c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    chunk->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED);
7934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
7935c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (chunk->owner()->identity() == LO_SPACE) {
7936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // StoreBuffer::Filter relies on MemoryChunk::FromAnyPointerAddress.
7937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // If FromAnyPointerAddress encounters a slot that belongs to a large
7938c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // chunk queued for deletion it will fail to find the chunk because
7939c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // it try to perform a search in the list of pages owned by of the large
7940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // object space and queued chunks were detached from that list.
7941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // To work around this we split large chunk into normal kPageSize aligned
79422c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org      // pieces and initialize size, owner and flags field of every piece.
79432c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org      // If FromAnyPointerAddress encounters a slot that belongs to one of
7944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // these smaller pieces it will treat it as a slot on a normal Page.
79459a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org      Address chunk_end = chunk->address() + chunk->size();
7946c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      MemoryChunk* inner = MemoryChunk::FromAddress(
7947c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          chunk->address() + Page::kPageSize);
79489a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org      MemoryChunk* inner_last = MemoryChunk::FromAddress(chunk_end - 1);
7949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      while (inner <= inner_last) {
7950c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Size of a large chunk is always a multiple of
795104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org        // OS::AllocateAlignment() so there is always
7952c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // enough space for a fake MemoryChunk header.
79539a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org        Address area_end = Min(inner->address() + Page::kPageSize, chunk_end);
79549a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org        // Guard against overflow.
79559a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org        if (area_end < inner->address()) area_end = chunk_end;
79569a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org        inner->SetArea(inner->address(), area_end);
79572c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org        inner->set_size(Page::kPageSize);
7958c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        inner->set_owner(lo_space());
7959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        inner->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED);
7960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        inner = MemoryChunk::FromAddress(
7961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            inner->address() + Page::kPageSize);
7962c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
7963c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
7964c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
7965c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  isolate_->heap()->store_buffer()->Compact();
7966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED);
7967c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) {
7968c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    next = chunk->next_chunk();
7969c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    isolate_->memory_allocator()->Free(chunk);
7970c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
7971c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  chunks_queued_for_free_ = NULL;
7972c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
7973c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
79742c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
79752c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgvoid Heap::RememberUnmappedPage(Address page, bool compacted) {
79762c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  uintptr_t p = reinterpret_cast<uintptr_t>(page);
79772c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  // Tag the page pointer to make it findable in the dump file.
79782c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  if (compacted) {
79792c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    p ^= 0xc1ead & (Page::kPageSize - 1);  // Cleared.
79802c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  } else {
79812c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    p ^= 0x1d1ed & (Page::kPageSize - 1);  // I died.
79822c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  }
79832c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  remembered_unmapped_pages_[remembered_unmapped_pages_index_] =
79842c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      reinterpret_cast<Address>(p);
79852c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  remembered_unmapped_pages_index_++;
79862c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  remembered_unmapped_pages_index_ %= kRememberedUnmappedPages;
79872c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org}
79882c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
798928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
799028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid Heap::ClearObjectStats(bool clear_last_time_stats) {
799128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  memset(object_counts_, 0, sizeof(object_counts_));
799228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  memset(object_sizes_, 0, sizeof(object_sizes_));
799328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  if (clear_last_time_stats) {
799428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    memset(object_counts_last_time_, 0, sizeof(object_counts_last_time_));
799528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    memset(object_sizes_last_time_, 0, sizeof(object_sizes_last_time_));
799628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  }
799728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org}
799828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
799928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
800028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgstatic LazyMutex checkpoint_object_stats_mutex = LAZY_MUTEX_INITIALIZER;
800128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
800228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
800328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid Heap::CheckpointObjectStats() {
800428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  ScopedLock lock(checkpoint_object_stats_mutex.Pointer());
800528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  Counters* counters = isolate()->counters();
800628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org#define ADJUST_LAST_TIME_OBJECT_COUNT(name)                                    \
800728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  counters->count_of_##name()->Increment(                                      \
800828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      static_cast<int>(object_counts_[name]));                                 \
800928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  counters->count_of_##name()->Decrement(                                      \
801028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      static_cast<int>(object_counts_last_time_[name]));                       \
801128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  counters->size_of_##name()->Increment(                                       \
801228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      static_cast<int>(object_sizes_[name]));                                  \
801328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  counters->size_of_##name()->Decrement(                                       \
801428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      static_cast<int>(object_sizes_last_time_[name]));
801528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
801628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org#undef ADJUST_LAST_TIME_OBJECT_COUNT
8017753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  int index;
8018753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#define ADJUST_LAST_TIME_OBJECT_COUNT(name)               \
8019753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  index = FIRST_CODE_KIND_SUB_TYPE + Code::name;          \
8020753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  counters->count_of_CODE_TYPE_##name()->Increment(       \
8021753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(object_counts_[index]));           \
8022753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  counters->count_of_CODE_TYPE_##name()->Decrement(       \
8023753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(object_counts_last_time_[index])); \
8024753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  counters->size_of_CODE_TYPE_##name()->Increment(        \
8025753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(object_sizes_[index]));            \
8026753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  counters->size_of_CODE_TYPE_##name()->Decrement(        \
8027753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(object_sizes_last_time_[index]));
8028753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  CODE_KIND_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
8029753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#undef ADJUST_LAST_TIME_OBJECT_COUNT
8030304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#define ADJUST_LAST_TIME_OBJECT_COUNT(name)               \
8031304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  index = FIRST_FIXED_ARRAY_SUB_TYPE + name;              \
8032304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  counters->count_of_FIXED_ARRAY_##name()->Increment(     \
8033304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      static_cast<int>(object_counts_[index]));           \
8034304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  counters->count_of_FIXED_ARRAY_##name()->Decrement(     \
8035304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      static_cast<int>(object_counts_last_time_[index])); \
8036304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  counters->size_of_FIXED_ARRAY_##name()->Increment(      \
8037304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      static_cast<int>(object_sizes_[index]));            \
8038304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  counters->size_of_FIXED_ARRAY_##name()->Decrement(      \
8039304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      static_cast<int>(object_sizes_last_time_[index]));
8040304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
8041304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#undef ADJUST_LAST_TIME_OBJECT_COUNT
8042753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
8043e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
8044e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
804528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  ClearObjectStats();
804628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org}
804728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
8048ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
8049ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgHeap::RelocationLock::RelocationLock(Heap* heap) : heap_(heap) {
8050ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (FLAG_parallel_recompilation) {
8051ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    heap_->relocation_mutex_->Lock();
8052ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#ifdef DEBUG
8053ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    heap_->relocation_mutex_locked_by_optimizer_thread_ =
8054ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread();
8055ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#endif  // DEBUG
8056ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
8057ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
8058ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
805943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
8060