12efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/accessors.h"
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h"
921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#include "src/base/bits.h"
101e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/once.h"
115de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/utils/random-number-generator.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compilation-cache.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/conversions.h"
16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h"
17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h"
18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h"
19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/global-handles.h"
20e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/heap/gc-idle-time-handler.h"
213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/incremental-marking.h"
223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/mark-compact.h"
238640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#include "src/heap/objects-visiting-inl.h"
248640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#include "src/heap/objects-visiting.h"
2531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org#include "src/heap/store-buffer.h"
26196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/heap-profiler.h"
27196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h"
28196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/natives.h"
29196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime-profiler.h"
30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopeinfo.h"
31196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/snapshot.h"
32196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h"
33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8threads.h"
34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/vm-state-inl.h"
354b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
36c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/regexp-macro-assembler.h"          // NOLINT
384b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/arm/regexp-macro-assembler-arm.h"  // NOLINT
3918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif
407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#if V8_TARGET_ARCH_MIPS && !V8_INTERPRETED_REGEXP
413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/regexp-macro-assembler.h"            // NOLINT
424b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/mips/regexp-macro-assembler-mips.h"  // NOLINT
437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#endif
4412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#if V8_TARGET_ARCH_MIPS64 && !V8_INTERPRETED_REGEXP
4512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/regexp-macro-assembler.h"
4612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/mips64/regexp-macro-assembler-mips64.h"
4712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif
4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
5071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
527276f14ca716596e0a0d17539516370c1f453847kasper.lund
53ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgHeap::Heap()
541e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    : amount_of_external_allocated_memory_(0),
551e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      amount_of_external_allocated_memory_at_last_global_gc_(0),
561e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      isolate_(NULL),
575b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      code_range_size_(0),
587c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org      // semispace_size_ should be a power of 2 and old_generation_size_ should
592b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org      // be a multiple of Page::kPageSize.
60cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org      reserved_semispace_size_(8 * (kPointerSize / 4) * MB),
617c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org      max_semi_space_size_(8 * (kPointerSize / 4) * MB),
6264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      initial_semispace_size_(Page::kPageSize),
63cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org      max_old_generation_size_(700ul * (kPointerSize / 4) * MB),
64cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org      max_executable_size_(256ul * (kPointerSize / 4) * MB),
657c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org      // Variables set based on semispace_size_ and old_generation_size_ in
667c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org      // ConfigureHeap.
677c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org      // Will be 4 * reserved_semispace_size_ to ensure that young
687c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org      // generation can be aligned to its size.
69057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      maximum_committed_(0),
70ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      survived_since_last_expansion_(0),
71ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      sweep_generation_(0),
72ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      always_allocate_scope_depth_(0),
73ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      contexts_disposed_(0),
7488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      global_ic_age_(0),
75c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org      flush_monomorphic_ics_(false),
76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      scan_on_scavenge_pages_(0),
77ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      new_space_(this),
78ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      old_pointer_space_(NULL),
79ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      old_data_space_(NULL),
80ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      code_space_(NULL),
81ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      map_space_(NULL),
82ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      cell_space_(NULL),
8341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      property_cell_space_(NULL),
84ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      lo_space_(NULL),
85ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      gc_state_(NOT_IN_GC),
86d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      gc_post_processing_depth_(0),
874b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      allocations_count_(0),
884b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      raw_allocations_hash_(0),
894b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc),
90ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      ms_count_(0),
91ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      gc_count_(0),
922c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      remembered_unmapped_pages_index_(0),
93ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      unflattened_strings_length_(0),
947276f14ca716596e0a0d17539516370c1f453847kasper.lund#ifdef DEBUG
95ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      allocation_timeout_(0),
9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // DEBUG
97a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit),
98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      old_gen_exhausted_(false),
99b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      inline_allocation_disabled_(false),
100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      store_buffer_rebuilder_(store_buffer()),
1014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      hidden_string_(NULL),
102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      gc_safe_size_of_old_object_(NULL),
1037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      total_regexp_code_generated_(0),
104474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      tracer_(this),
105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      high_survival_rate_period_length_(0),
1066a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      promoted_objects_size_(0),
1076a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      promotion_rate_(0),
1086a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      semi_space_copied_object_size_(0),
1096a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      semi_space_copied_rate_(0),
11093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org      nodes_died_in_new_space_(0),
11193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org      nodes_copied_in_new_space_(0),
11293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org      nodes_promoted_(0),
113196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      maximum_size_scavenges_(0),
114c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      max_gc_pause_(0.0),
115c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      total_gc_time_ms_(0.0),
116ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      max_alive_after_gc_(0),
117ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      min_in_mutator_(kMaxInt),
118e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org      marking_time_(0.0),
119e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org      sweeping_time_(0.0),
120c8cbc43a1fd5fda5d6a1e172f720cbd1215157c8machenbach@chromium.org      mark_compact_collector_(this),
121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      store_buffer_(this),
122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      marking_(this),
123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      incremental_marking_(this),
124ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org      gc_count_at_last_idle_gc_(0),
125a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      full_codegen_bytes_generated_(0),
126a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      crankshaft_codegen_bytes_generated_(0),
12732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      gcs_since_last_deopt_(0),
12894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#ifdef VERIFY_HEAP
12925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      no_weak_object_verification_scope_depth_(0),
13094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#endif
131bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org      allocation_sites_scratchpad_length_(0),
132c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      promotion_queue_(this),
133ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      configured_(false),
134c8cbc43a1fd5fda5d6a1e172f720cbd1215157c8machenbach@chromium.org      external_string_table_(this),
135ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      chunks_queued_for_free_(NULL),
1362904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      gc_callbacks_depth_(0) {
1373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// Allow build-time customization of the max semispace size. Building
1383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// V8 with snapshots and a non-default max semispace size is much
1393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// easier if you can define it as part of the build environment.
140ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#if defined(V8_MAX_SEMISPACE_SIZE)
1413c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
142ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif
143ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
144cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  // Ensure old_generation_size_ is a multiple of kPageSize.
145e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(MB >= Page::kPageSize);
146cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org
147ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
1483c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  set_native_contexts_list(NULL);
1493c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  set_array_buffers_list(Smi::FromInt(0));
1503c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  set_allocation_sites_list(Smi::FromInt(0));
151196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  set_encountered_weak_collections(Smi::FromInt(0));
152cb9affa86506f210b7d9b425012b1026b4fd0f2fyangguo@chromium.org  // Put a dummy entry in the remembered pages so we can find the list the
153cb9affa86506f210b7d9b425012b1026b4fd0f2fyangguo@chromium.org  // minidump even if there are no real unmapped pages.
154cb9affa86506f210b7d9b425012b1026b4fd0f2fyangguo@chromium.org  RememberUnmappedPage(NULL, false);
15528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
15628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  ClearObjectStats(true);
157ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
15843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
160f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.orgintptr_t Heap::Capacity() {
161f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return 0;
16243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  return new_space_.Capacity() + old_pointer_space_->Capacity() +
1643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         old_data_space_->Capacity() + code_space_->Capacity() +
1653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         map_space_->Capacity() + cell_space_->Capacity() +
1663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         property_cell_space_->Capacity();
16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
16843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
170f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.orgintptr_t Heap::CommittedMemory() {
171f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return 0;
1723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
1733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  return new_space_.CommittedMemory() + old_pointer_space_->CommittedMemory() +
1743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         old_data_space_->CommittedMemory() + code_space_->CommittedMemory() +
1753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         map_space_->CommittedMemory() + cell_space_->CommittedMemory() +
1763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         property_cell_space_->CommittedMemory() + lo_space_->Size();
1773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
1783811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
17972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
18072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgsize_t Heap::CommittedPhysicalMemory() {
18172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  if (!HasBeenSetUp()) return 0;
18272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
18372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return new_space_.CommittedPhysicalMemory() +
1843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         old_pointer_space_->CommittedPhysicalMemory() +
1853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         old_data_space_->CommittedPhysicalMemory() +
1863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         code_space_->CommittedPhysicalMemory() +
1873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         map_space_->CommittedPhysicalMemory() +
1883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         cell_space_->CommittedPhysicalMemory() +
1893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         property_cell_space_->CommittedPhysicalMemory() +
1903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         lo_space_->CommittedPhysicalMemory();
19172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
19272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
19372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
19401fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.orgintptr_t Heap::CommittedMemoryExecutable() {
195f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return 0;
19601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
197ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate()->memory_allocator()->SizeExecutable();
19801fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org}
19901fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
2003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
201057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid Heap::UpdateMaximumCommitted() {
202057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (!HasBeenSetUp()) return;
203057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
204057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  intptr_t current_committed_memory = CommittedMemory();
205057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (current_committed_memory > maximum_committed_) {
206057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    maximum_committed_ = current_committed_memory;
207057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  }
208057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org}
209057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
210057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
211f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.orgintptr_t Heap::Available() {
212f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return 0;
21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  return new_space_.Available() + old_pointer_space_->Available() +
2153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         old_data_space_->Available() + code_space_->Available() +
2163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         map_space_->Available() + cell_space_->Available() +
2173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         property_cell_space_->Available();
21843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
21943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
221f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.combool Heap::HasBeenSetUp() {
2223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  return old_pointer_space_ != NULL && old_data_space_ != NULL &&
2233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         code_space_ != NULL && map_space_ != NULL && cell_space_ != NULL &&
2243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         property_cell_space_ != NULL && lo_space_ != NULL;
22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
22643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
228d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgint Heap::GcSafeSizeOfOldObject(HeapObject* object) {
229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (IntrusiveMarking::IsMarked(object)) {
230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return IntrusiveMarking::SizeOfMarkedObject(object);
231d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return object->SizeFromMap(object->map());
233d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org}
234d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
235d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
236994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgGarbageCollector Heap::SelectGarbageCollector(AllocationSpace space,
237994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                                              const char** reason) {
23843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Is global GC requested?
239efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  if (space != NEW_SPACE) {
240ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->counters()->gc_compactor_caused_by_request()->Increment();
241994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    *reason = "GC in old space requested";
24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return MARK_COMPACTOR;
24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
245efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) {
246efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org    *reason = "GC in old space forced by flags";
247efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org    return MARK_COMPACTOR;
248efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  }
249efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Is enough data promoted to justify a global GC?
251a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (OldGenerationAllocationLimitReached()) {
252ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->counters()->gc_compactor_caused_by_promoted_data()->Increment();
253994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    *reason = "promotion limit reached";
25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return MARK_COMPACTOR;
25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Have allocation in OLD and LO failed?
25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (old_gen_exhausted_) {
2593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->counters()
2603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        ->gc_compactor_caused_by_oldspace_exhaustion()
2613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        ->Increment();
262994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    *reason = "old generations exhausted";
26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return MARK_COMPACTOR;
26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Is there enough space left in OLD to guarantee that a scavenge can
26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // succeed?
26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
2699258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // Note that MemoryAllocator->MaxAvailable() undercounts the memory available
27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for object promotion. It counts only the bytes that the memory
27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // allocator has not yet allocated from the OS and assigned to any space,
27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // and does not count available bytes already in the old space or code
27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // space.  Undercounting is safe---we may get an unrequested full GC when
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // a scavenge would have succeeded.
275ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (isolate_->memory_allocator()->MaxAvailable() <= new_space_.Size()) {
2763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->counters()
2773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        ->gc_compactor_caused_by_oldspace_exhaustion()
2783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        ->Increment();
279994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    *reason = "scavenge might not succeed";
28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return MARK_COMPACTOR;
28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Default
284994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  *reason = NULL;
28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return SCAVENGER;
28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// TODO(1238405): Combine the infrastructure for --heap-stats and
29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// --log-gc to avoid the complicated preprocessor and flag testing.
29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ReportStatisticsBeforeGC() {
2923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// Heap::ReportHeapStatistics will also log NewSpace statistics when
2933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// compiled --log-gc is set.  The following logic is used to avoid
2943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// double logging.
295030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#ifdef DEBUG
2965a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  if (FLAG_heap_stats || FLAG_log_gc) new_space_.CollectStatistics();
29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_heap_stats) {
29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ReportHeapStatistics("Before GC");
29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (FLAG_log_gc) {
3005a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.ReportStatistics();
30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3025a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  if (FLAG_heap_stats || FLAG_log_gc) new_space_.ClearHistograms();
303030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#else
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_log_gc) {
3055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.CollectStatistics();
3065a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.ReportStatistics();
3075a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.ClearHistograms();
30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
309030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif  // DEBUG
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
313e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgvoid Heap::PrintShortHeapStatistics() {
314e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  if (!FLAG_trace_gc_verbose) return;
3153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("Memory allocator,   used: %6" V8_PTR_PREFIX
3163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX "d KB\n",
318657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           isolate_->memory_allocator()->Size() / KB,
319657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           isolate_->memory_allocator()->Available() / KB);
3203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("New space,          used: %6" V8_PTR_PREFIX
3213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX
3233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", committed: %6" V8_PTR_PREFIX "d KB\n",
3253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           new_space_.Size() / KB, new_space_.Available() / KB,
326657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           new_space_.CommittedMemory() / KB);
3273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("Old pointers,       used: %6" V8_PTR_PREFIX
3283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX
3303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", committed: %6" V8_PTR_PREFIX "d KB\n",
332657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_pointer_space_->SizeOfObjects() / KB,
333657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_pointer_space_->Available() / KB,
334657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_pointer_space_->CommittedMemory() / KB);
3353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("Old data space,     used: %6" V8_PTR_PREFIX
3363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX
3383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", committed: %6" V8_PTR_PREFIX "d KB\n",
340657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_data_space_->SizeOfObjects() / KB,
341657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_data_space_->Available() / KB,
342657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           old_data_space_->CommittedMemory() / KB);
3433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("Code space,         used: %6" V8_PTR_PREFIX
3443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX
3463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", committed: %6" V8_PTR_PREFIX "d KB\n",
3483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           code_space_->SizeOfObjects() / KB, code_space_->Available() / KB,
349657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           code_space_->CommittedMemory() / KB);
3503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("Map space,          used: %6" V8_PTR_PREFIX
3513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX
3533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", committed: %6" V8_PTR_PREFIX "d KB\n",
3553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           map_space_->SizeOfObjects() / KB, map_space_->Available() / KB,
356657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           map_space_->CommittedMemory() / KB);
3573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("Cell space,         used: %6" V8_PTR_PREFIX
3583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX
3603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", committed: %6" V8_PTR_PREFIX "d KB\n",
3623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           cell_space_->SizeOfObjects() / KB, cell_space_->Available() / KB,
363657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           cell_space_->CommittedMemory() / KB);
3643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("PropertyCell space, used: %6" V8_PTR_PREFIX
3653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX
3673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", committed: %6" V8_PTR_PREFIX "d KB\n",
36941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org           property_cell_space_->SizeOfObjects() / KB,
37041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org           property_cell_space_->Available() / KB,
37141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org           property_cell_space_->CommittedMemory() / KB);
3723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("Large object space, used: %6" V8_PTR_PREFIX
3733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX
3753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", committed: %6" V8_PTR_PREFIX "d KB\n",
3773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           lo_space_->SizeOfObjects() / KB, lo_space_->Available() / KB,
378657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org           lo_space_->CommittedMemory() / KB);
3793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintPID("All spaces,         used: %6" V8_PTR_PREFIX
3803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", available: %6" V8_PTR_PREFIX
3823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           "d KB"
3833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           ", committed: %6" V8_PTR_PREFIX "d KB\n",
3843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           this->SizeOfObjects() / KB, this->Available() / KB,
38533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org           this->CommittedMemory() / KB);
386f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org  PrintPID("External memory reported: %6" V8_PTR_PREFIX "d KB\n",
3877ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org           static_cast<intptr_t>(amount_of_external_allocated_memory_ / KB));
388c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  PrintPID("Total time spent in GC  : %.1f ms\n", total_gc_time_ms_);
389e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org}
390e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
391e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
39243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// TODO(1238405): Combine the infrastructure for --heap-stats and
39343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// --log-gc to avoid the complicated preprocessor and flag testing.
39443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ReportStatisticsAfterGC() {
3953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// Similar to the before GC, we use some complicated logic to ensure that
3963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// NewSpace statistics are logged exactly once when --log-gc is turned on.
397030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#if defined(DEBUG)
39843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_heap_stats) {
3992abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    new_space_.CollectStatistics();
40043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ReportHeapStatistics("After GC");
40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (FLAG_log_gc) {
4025a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    new_space_.ReportStatistics();
40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
404030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#else
4055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  if (FLAG_log_gc) new_space_.ReportStatistics();
406030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif  // DEBUG
40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgvoid Heap::GarbageCollectionPrologue() {
4113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
4123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllowHeapAllocation for_the_first_part_of_prologue;
41379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    ClearJSFunctionResultCaches();
41479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    gc_count_++;
41579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    unflattened_strings_length_ = 0;
41643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    if (FLAG_flush_code && FLAG_flush_code_incrementally) {
41879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      mark_compact_collector()->EnableCodeFlushing(true);
41979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    }
420e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
421c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
42279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    if (FLAG_verify_heap) {
42379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      Verify();
42479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    }
425c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
42679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  }
427c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
4286a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // Reset GC statistics.
4296a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  promoted_objects_size_ = 0;
4306a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  semi_space_copied_object_size_ = 0;
43193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  nodes_died_in_new_space_ = 0;
43293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  nodes_copied_in_new_space_ = 0;
43393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  nodes_promoted_ = 0;
4346a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
435057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  UpdateMaximumCommitted();
436057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
437c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef DEBUG
438e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC);
43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_gc_verbose) Print();
44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ReportStatisticsBeforeGC();
443030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif  // DEBUG
4440ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
44570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  store_buffer()->GCPrologue();
4462ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org
4479af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (isolate()->concurrent_osr_enabled()) {
4482ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org    isolate()->optimizing_compiler_thread()->AgeBufferedOsrJobs();
4492ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org  }
450196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
451196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (new_space_.IsAtMaximumCapacity()) {
452196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    maximum_size_scavenges_++;
453196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  } else {
454196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    maximum_size_scavenges_ = 0;
455196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
456196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CheckNewSpaceExpansionCriteria();
45743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
460f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.orgintptr_t Heap::SizeOfObjects() {
461f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  intptr_t total = 0;
4627c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  AllSpaces spaces(this);
463b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
4644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com    total += space->SizeOfObjects();
465911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  }
4669258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  return total;
46743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
46843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
470e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid Heap::ClearAllICsByKind(Code::Kind kind) {
471e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  HeapObjectIterator it(code_space());
472e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
473e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  for (Object* object = it.Next(); object != NULL; object = it.Next()) {
474e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Code* code = Code::cast(object);
475e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Code::Kind current_kind = code->kind();
476e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    if (current_kind == Code::FUNCTION ||
477e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        current_kind == Code::OPTIMIZED_FUNCTION) {
478e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      code->ClearInlineCaches(kind);
479e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    }
480e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
481e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org}
482e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
483e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
48456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.orgvoid Heap::RepairFreeListsAfterBoot() {
4857c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  PagedSpaces spaces(this);
4863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (PagedSpace* space = spaces.next(); space != NULL;
48756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org       space = spaces.next()) {
48856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    space->RepairFreeListsAfterBoot();
48956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  }
49056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org}
49156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
49256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
49371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.orgvoid Heap::ProcessPretenuringFeedback() {
49409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  if (FLAG_allocation_site_pretenuring) {
495c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    int tenure_decisions = 0;
496c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    int dont_tenure_decisions = 0;
497c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    int allocation_mementos_found = 0;
49871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    int allocation_sites = 0;
49971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    int active_allocation_sites = 0;
50071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org
50171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    // If the scratchpad overflowed, we have to iterate over the allocation
502034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    // sites list.
503196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    // TODO(hpayer): We iterate over the whole list of allocation sites when
504196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    // we grew to the maximum semi-space size to deopt maybe tenured
505196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    // allocation sites. We could hold the maybe tenured allocation sites
506196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    // in a seperate data structure if this is a performance problem.
507196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    bool deopt_maybe_tenured = DeoptMaybeTenuredAllocationSites();
50871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    bool use_scratchpad =
5093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        allocation_sites_scratchpad_length_ < kAllocationSiteScratchpadSize &&
5103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        !deopt_maybe_tenured;
51171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org
51271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    int i = 0;
51371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    Object* list_element = allocation_sites_list();
5145c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    bool trigger_deoptimization = false;
515196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    bool maximum_size_scavenge = MaximumSizeScavenge();
5163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    while (use_scratchpad ? i < allocation_sites_scratchpad_length_
5173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                          : list_element->IsAllocationSite()) {
5183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      AllocationSite* site =
5193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          use_scratchpad
5203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              ? AllocationSite::cast(allocation_sites_scratchpad()->get(i))
5213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              : AllocationSite::cast(list_element);
5224ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      allocation_mementos_found += site->memento_found_count();
5234ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      if (site->memento_found_count() > 0) {
52471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org        active_allocation_sites++;
525196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        if (site->DigestPretenuringFeedback(maximum_size_scavenge)) {
526196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          trigger_deoptimization = true;
527196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        }
528196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        if (site->GetPretenureMode() == TENURED) {
529196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          tenure_decisions++;
530196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        } else {
531196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          dont_tenure_decisions++;
532196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        }
533196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        allocation_sites++;
53471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org      }
535196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
536196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (deopt_maybe_tenured && site->IsMaybeTenure()) {
537196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        site->set_deopt_dependent_code(true);
538196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        trigger_deoptimization = true;
539c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org      }
540196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
54171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org      if (use_scratchpad) {
54271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org        i++;
54371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org      } else {
54471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org        list_element = site->weak_next();
54571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org      }
546c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    }
5475c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
548f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (trigger_deoptimization) {
5493c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      isolate_->stack_guard()->RequestDeoptMarkedAllocationSites();
550f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
5515c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
552bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org    FlushAllocationSitesScratchpad();
553c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
55425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    if (FLAG_trace_pretenuring_statistics &&
5553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        (allocation_mementos_found > 0 || tenure_decisions > 0 ||
556c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org         dont_tenure_decisions > 0)) {
5573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      PrintF(
5583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          "GC: (mode, #visited allocation sites, #active allocation sites, "
5593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          "#mementos, #tenure decisions, #donttenure decisions) "
5603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          "(%s, %d, %d, %d, %d, %d)\n",
5613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          use_scratchpad ? "use scratchpad" : "use list", allocation_sites,
5623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          active_allocation_sites, allocation_mementos_found, tenure_decisions,
5633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          dont_tenure_decisions);
564c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    }
565c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org  }
56671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org}
56771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org
568c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
569f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid Heap::DeoptMarkedAllocationSites() {
570f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // TODO(hpayer): If iterating over the allocation sites list becomes a
571f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // performance issue, use a cache heap data structure instead (similar to the
572f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // allocation sites scratchpad).
573f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Object* list_element = allocation_sites_list();
574f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  while (list_element->IsAllocationSite()) {
575f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    AllocationSite* site = AllocationSite::cast(list_element);
576f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (site->deopt_dependent_code()) {
577f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      site->dependent_code()->MarkCodeForDeoptimization(
5783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          isolate_, DependentCode::kAllocationSiteTenuringChangedGroup);
579f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      site->set_deopt_dependent_code(false);
580f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
581f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    list_element = site->weak_next();
582f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
583f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Deoptimizer::DeoptimizeMarkedCode(isolate_);
584f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
586f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
58771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.orgvoid Heap::GarbageCollectionEpilogue() {
588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->GCEpilogue();
58943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
590c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // In release mode, we only zap the from space under heap verification.
591c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  if (Heap::ShouldZapGarbage()) {
592c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    ZapFromSpace();
593c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  }
594c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
595f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Process pretenuring feedback and update allocation sites.
596f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ProcessPretenuringFeedback();
597f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
598c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
59943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_verify_heap) {
60043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Verify();
60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
602c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
60343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowHeapAllocation for_the_rest_of_the_epilogue;
60579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org
606c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef DEBUG
607ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (FLAG_print_global_handles) isolate_->global_handles()->Print();
60843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_print_handles) PrintHandles();
60943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_gc_verbose) Print();
61043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_code_stats) ReportCodeStatistics("After GC");
61143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
61232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (FLAG_deopt_every_n_garbage_collections > 0) {
613486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // TODO(jkummerow/ulan/jarin): This is not safe! We can't assume that
614486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // the topmost optimized frame can be deoptimized safely, because it
615486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // might not have a lazy bailout point right after its current PC.
61632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (++gcs_since_last_deopt_ == FLAG_deopt_every_n_garbage_collections) {
61732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      Deoptimizer::DeoptimizeAll(isolate());
61832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      gcs_since_last_deopt_ = 0;
61932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    }
62032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
62143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
622057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  UpdateMaximumCommitted();
623057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
624ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->counters()->alive_after_last_gc()->Set(
625ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      static_cast<int>(SizeOfObjects()));
62643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  isolate_->counters()->string_table_capacity()->Set(
6284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      string_table()->Capacity());
629ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->counters()->number_of_symbols()->Set(
6304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      string_table()->NumberOfElements());
6317a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
632a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  if (full_codegen_bytes_generated_ + crankshaft_codegen_bytes_generated_ > 0) {
633a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    isolate_->counters()->codegen_fraction_crankshaft()->AddSample(
634a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        static_cast<int>((crankshaft_codegen_bytes_generated_ * 100.0) /
6353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                         (crankshaft_codegen_bytes_generated_ +
6363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                          full_codegen_bytes_generated_)));
637a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
638a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
639753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (CommittedMemory() > 0) {
640753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    isolate_->counters()->external_fragmentation_total()->AddSample(
641753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org        static_cast<int>(100 - (SizeOfObjects() * 100.0) / CommittedMemory()));
642471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
6433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->counters()->heap_fraction_new_space()->AddSample(static_cast<int>(
6443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        (new_space()->CommittedMemory() * 100.0) / CommittedMemory()));
645a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    isolate_->counters()->heap_fraction_old_pointer_space()->AddSample(
6463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        static_cast<int>((old_pointer_space()->CommittedMemory() * 100.0) /
6473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                         CommittedMemory()));
648a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    isolate_->counters()->heap_fraction_old_data_space()->AddSample(
6493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        static_cast<int>((old_data_space()->CommittedMemory() * 100.0) /
6503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                         CommittedMemory()));
6513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->counters()->heap_fraction_code_space()->AddSample(
6523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        static_cast<int>((code_space()->CommittedMemory() * 100.0) /
6533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                         CommittedMemory()));
6543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->counters()->heap_fraction_map_space()->AddSample(static_cast<int>(
6553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        (map_space()->CommittedMemory() * 100.0) / CommittedMemory()));
656471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_fraction_cell_space()->AddSample(
6573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        static_cast<int>((cell_space()->CommittedMemory() * 100.0) /
6583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                         CommittedMemory()));
6593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->counters()->heap_fraction_property_cell_space()->AddSample(
6603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        static_cast<int>((property_cell_space()->CommittedMemory() * 100.0) /
6613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                         CommittedMemory()));
6623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->counters()->heap_fraction_lo_space()->AddSample(static_cast<int>(
6633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        (lo_space()->CommittedMemory() * 100.0) / CommittedMemory()));
664471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
665471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_sample_total_committed()->AddSample(
666471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(CommittedMemory() / KB));
667471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_sample_total_used()->AddSample(
668471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(SizeOfObjects() / KB));
669471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_sample_map_space_committed()->AddSample(
670471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(map_space()->CommittedMemory() / KB));
671471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    isolate_->counters()->heap_sample_cell_space_committed()->AddSample(
672471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        static_cast<int>(cell_space()->CommittedMemory() / KB));
6733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->counters()
6743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        ->heap_sample_property_cell_space_committed()
6753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        ->AddSample(
6763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            static_cast<int>(property_cell_space()->CommittedMemory() / KB));
677a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    isolate_->counters()->heap_sample_code_space_committed()->AddSample(
678a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        static_cast<int>(code_space()->CommittedMemory() / KB));
679057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
680057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    isolate_->counters()->heap_sample_maximum_committed()->AddSample(
681057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org        static_cast<int>(MaximumCommittedMemory() / KB));
682753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  }
683753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define UPDATE_COUNTERS_FOR_SPACE(space)                \
6853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  isolate_->counters()->space##_bytes_available()->Set( \
6863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      static_cast<int>(space()->Available()));          \
6873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  isolate_->counters()->space##_bytes_committed()->Set( \
6883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      static_cast<int>(space()->CommittedMemory()));    \
6893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  isolate_->counters()->space##_bytes_used()->Set(      \
690753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(space()->SizeOfObjects()));
6913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define UPDATE_FRAGMENTATION_FOR_SPACE(space)                          \
6923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (space()->CommittedMemory() > 0) {                                \
6933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->counters()->external_fragmentation_##space()->AddSample( \
6943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        static_cast<int>(100 -                                         \
6953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                         (space()->SizeOfObjects() * 100.0) /          \
6963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                             space()->CommittedMemory()));             \
6973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
6983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(space) \
6993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  UPDATE_COUNTERS_FOR_SPACE(space)                         \
700753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_FRAGMENTATION_FOR_SPACE(space)
701753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
70228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  UPDATE_COUNTERS_FOR_SPACE(new_space)
703753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_pointer_space)
704753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_data_space)
705753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(code_space)
706753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(map_space)
707753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(cell_space)
70841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(property_cell_space)
709753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(lo_space)
71028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org#undef UPDATE_COUNTERS_FOR_SPACE
711753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#undef UPDATE_FRAGMENTATION_FOR_SPACE
712753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE
7137a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
714865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org#ifdef DEBUG
71543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ReportStatisticsAfterGC();
716030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif  // DEBUG
717fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
718fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // Remember the last top pointer so that we can later find out
719fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // whether we allocated in new space since the last GC.
720fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  new_space_top_after_last_gc_ = new_space()->top();
72143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
72243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid Heap::CollectAllGarbage(int flags, const char* gc_reason,
7254ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org                             const v8::GCCallbackFlags gc_callback_flags) {
7269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // Since we are ignoring the return value, the exact choice of space does
7279258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // not matter, so long as we do not specify NEW_SPACE, which would not
7289258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // cause a full GC.
729c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  mark_compact_collector_.SetFlags(flags);
7304ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  CollectGarbage(OLD_POINTER_SPACE, gc_reason, gc_callback_flags);
731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  mark_compact_collector_.SetFlags(kNoGCFlags);
7329258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
7339258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
7349258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
735994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgvoid Heap::CollectAllAvailableGarbage(const char* gc_reason) {
736f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Since we are ignoring the return value, the exact choice of space does
737f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // not matter, so long as we do not specify NEW_SPACE, which would not
738f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // cause a full GC.
739f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Major GC would invoke weak handle callbacks on weakly reachable
740f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // handles, but won't collect weakly reachable objects until next
741f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // major GC.  Therefore if we collect aggressively and weak handle callback
742f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // has been invoked, we rerun major GC to release objects which become
743f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // garbage.
744f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Note: as weak callbacks can execute arbitrary code, we cannot
745f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // hope that eventually there will be no weak callbacks invocations.
746f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Therefore stop recollecting after several attempts.
7479af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (isolate()->concurrent_recompilation_enabled()) {
7483d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    // The optimizing compiler may be unnecessarily holding on to memory.
7493d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    DisallowHeapAllocation no_recursive_gc;
7503d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    isolate()->optimizing_compiler_thread()->Flush();
7513d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  }
752994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  mark_compact_collector()->SetFlags(kMakeHeapIterableMask |
753994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                                     kReduceMemoryFootprintMask);
754c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  isolate_->compilation_cache()->Clear();
755f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  const int kMaxNumberOfAttempts = 7;
756bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  const int kMinNumberOfAttempts = 2;
757f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) {
7580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (!CollectGarbage(MARK_COMPACTOR, gc_reason, NULL) &&
759bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        attempt + 1 >= kMinNumberOfAttempts) {
760f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org      break;
761f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org    }
762f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  }
763c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  mark_compact_collector()->SetFlags(kNoGCFlags);
764c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  new_space_.Shrink();
765bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org  UncommitFromSpace();
766c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  incremental_marking()->UncommitMarkingDeque();
767f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org}
768f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
769f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
770f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid Heap::EnsureFillerObjectAtTop() {
771f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // There may be an allocation memento behind every object in new space.
772f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // If we evacuate a not full new space or if we are on the last page of
773f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // the new space, then there may be uninitialized memory behind the top
774f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // pointer of the new space page. We store a filler object there to
775f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // identify the unused space.
776f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Address from_top = new_space_.top();
777f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Address from_limit = new_space_.limit();
778f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (from_top < from_limit) {
779f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    int remaining_in_page = static_cast<int>(from_limit - from_top);
780f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    CreateFillerObjectAt(from_top, remaining_in_page);
781f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
782f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
783f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
784f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
7853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgbool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason,
7864ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org                          const char* collector_reason,
7874ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org                          const v8::GCCallbackFlags gc_callback_flags) {
78843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The VM is in the GC state until exiting this function.
789ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  VMState<GC> state(isolate_);
79043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
79243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Reset the allocation timeout to the GC interval, but make sure to
79343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // allow at least a few allocations after a collection. The reason
79443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for this is that we have a lot of allocation sequences and we
79543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // assume that a garbage collection will allow the subsequent
79643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // allocation attempts to go through.
79743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  allocation_timeout_ = Max(6, FLAG_gc_interval);
79843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
79943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
800f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  EnsureFillerObjectAtTop();
801b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org
802c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (collector == SCAVENGER && !incremental_marking()->IsStopped()) {
803c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (FLAG_trace_incremental_marking) {
804c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      PrintF("[IncrementalMarking] Scavenge during marking.\n");
805c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
806c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
807c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
808c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (collector == MARK_COMPACTOR &&
80983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      !mark_compact_collector()->abort_incremental_marking() &&
810c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !incremental_marking()->IsStopped() &&
811c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !incremental_marking()->should_hurry() &&
812c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      FLAG_incremental_marking_steps) {
8137d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    // Make progress in incremental marking.
8147d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    const intptr_t kStepSizeWhenDelayedByScavenge = 1 * MB;
8157d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    incremental_marking()->Step(kStepSizeWhenDelayedByScavenge,
8167d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org                                IncrementalMarking::NO_GC_VIA_STACK_GUARD);
817a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    if (!incremental_marking()->IsComplete() && !FLAG_gc_global) {
8187d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org      if (FLAG_trace_incremental_marking) {
8197d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org        PrintF("[IncrementalMarking] Delaying MarkSweep.\n");
8207d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org      }
8217d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org      collector = SCAVENGER;
8227d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org      collector_reason = "incremental marking delaying mark-sweep";
823c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
824c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
825c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
826f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  bool next_gc_likely_to_collect_more = false;
827f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
8287c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  {
829f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org    tracer()->Start(collector, gc_reason, collector_reason);
830e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(AllowHeapAllocation::IsAllowed());
83179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_allocation_during_gc;
83270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    GarbageCollectionPrologue();
83343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8348e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    {
8358e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      HistogramTimerScope histogram_timer_scope(
8368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          (collector == SCAVENGER) ? isolate_->counters()->gc_scavenger()
8378e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                   : isolate_->counters()->gc_compactor());
8388e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      next_gc_likely_to_collect_more =
839474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          PerformGarbageCollection(collector, gc_callback_flags);
8408e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
84143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    GarbageCollectionEpilogue();
843f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org    tracer()->Stop();
84443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
84543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Start incremental marking for the next cycle. The heap snapshot
84783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // generator needs incremental marking to stay off after it aborted.
84883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  if (!mark_compact_collector()->abort_incremental_marking() &&
849a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      WorthActivatingIncrementalMarking()) {
85083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    incremental_marking()->Start();
851c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
852c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
853f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  return next_gc_likely_to_collect_more;
85443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
85543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
857594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgint Heap::NotifyContextDisposed() {
8589af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (isolate()->concurrent_recompilation_enabled()) {
859594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Flush the queued recompilation tasks.
860594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    isolate()->optimizing_compiler_thread()->Flush();
861594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
862594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  flush_monomorphic_ics_ = true;
863e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  AgeInlineCaches();
864594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return ++contexts_disposed_;
865594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
866594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
867594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
8683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid Heap::MoveElements(FixedArray* array, int dst_index, int src_index,
86959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                        int len) {
87059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (len == 0) return;
87159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
872e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(array->map() != fixed_cow_array_map());
87359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  Object** dst_objects = array->data_start() + dst_index;
874d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize);
87559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (!InNewSpace(array)) {
87659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    for (int i = 0; i < len; i++) {
87759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      // TODO(hpayer): check store buffer for entries
87859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      if (InNewSpace(dst_objects[i])) {
87959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        RecordWrite(array->address(), array->OffsetOfElementAt(dst_index + i));
88059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      }
88159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    }
88259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
88359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  incremental_marking()->RecordWrites(array);
88459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org}
88559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
88659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
887c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
8884a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org// Helper class for verifying the string table.
8894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgclass StringTableVerifier : public ObjectVisitor {
890416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org public:
891416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org  void VisitPointers(Object** start, Object** end) {
892416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org    // Visit all HeapObject pointers in [start, end).
893416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org    for (Object** p = start; p < end; p++) {
894416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org      if ((*p)->IsHeapObject()) {
8954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        // Check that the string is actually internalized.
8964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        CHECK((*p)->IsTheHole() || (*p)->IsUndefined() ||
8974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              (*p)->IsInternalizedString());
898d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org      }
899d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org    }
900416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org  }
901416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org};
902d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
903416c5b0a9354c0e058499fb00384edefe874e1fbkasperl@chromium.org
904c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgstatic void VerifyStringTable(Heap* heap) {
9054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  StringTableVerifier verifier;
906c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  heap->string_table()->IterateElements(&verifier);
907d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org}
908c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif  // VERIFY_HEAP
909d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
910d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
911bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comstatic bool AbortIncrementalMarkingAndCollectGarbage(
9123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Heap* heap, AllocationSpace space, const char* gc_reason = NULL) {
913bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  heap->mark_compact_collector()->SetFlags(Heap::kAbortIncrementalMarkingMask);
914bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  bool result = heap->CollectGarbage(space, gc_reason);
915bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  heap->mark_compact_collector()->SetFlags(Heap::kNoGCFlags);
916bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return result;
917bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
918bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
919bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
9203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid Heap::ReserveSpace(int* sizes, Address* locations_out) {
9210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  bool gc_performed = true;
92205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  int counter = 0;
92305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  static const int kThreshold = 20;
92405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  while (gc_performed && counter++ < kThreshold) {
9250c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    gc_performed = false;
926e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(NEW_SPACE == FIRST_PAGED_SPACE - 1);
92756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    for (int space = NEW_SPACE; space <= LAST_PAGED_SPACE; space++) {
92856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      if (sizes[space] != 0) {
929a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        AllocationResult allocation;
93056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        if (space == NEW_SPACE) {
93156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          allocation = new_space()->AllocateRaw(sizes[space]);
93256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        } else {
93356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          allocation = paged_space(space)->AllocateRaw(sizes[space]);
93456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        }
93556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        FreeListNode* node;
936a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        if (!allocation.To(&node)) {
93756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          if (space == NEW_SPACE) {
93856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org            Heap::CollectGarbage(NEW_SPACE,
93956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org                                 "failed to reserve space in the new space");
94056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          } else {
94156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org            AbortIncrementalMarkingAndCollectGarbage(
9423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                this, static_cast<AllocationSpace>(space),
94356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org                "failed to reserve space in paged space");
94456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          }
94556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          gc_performed = true;
94656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          break;
94756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        } else {
94856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          // Mark with a free list node, in case we have a GC before
94956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          // deserializing.
95056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          node->set_size(this, sizes[space]);
95156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org          locations_out[space] = node->address();
95256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        }
95356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      }
9540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
9550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
95605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
95705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (gc_performed) {
95805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    // Failed to reserve the space after several attempts.
95905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    V8::FatalProcessOutOfMemory("Heap::ReserveSpace");
96005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
9610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
9620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
9630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
964add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.orgvoid Heap::EnsureFromSpaceIsCommitted() {
965add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  if (new_space_.CommitFromSpaceIfNeeded()) return;
966add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org
967add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  // Committing memory to from space failed.
968add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  // Memory is exhausted and we will die.
969add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  V8::FatalProcessOutOfMemory("Committing semi space failed.");
970add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org}
971add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org
972add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org
973e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgvoid Heap::ClearJSFunctionResultCaches() {
974ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (isolate_->bootstrapper()->IsActive()) return;
975ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
9763c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Object* context = native_contexts_list();
977e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  while (!context->IsUndefined()) {
9787ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    // Get the caches for this context. GC can happen when the context
9797ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    // is not fully initialized, so the caches can be undefined.
9807ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    Object* caches_or_undefined =
9817ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        Context::cast(context)->get(Context::JSFUNCTION_RESULT_CACHES_INDEX);
9827ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    if (!caches_or_undefined->IsUndefined()) {
9837ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      FixedArray* caches = FixedArray::cast(caches_or_undefined);
9847ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      // Clear the caches:
9857ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      int length = caches->length();
9867ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      for (int i = 0; i < length; i++) {
9877ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        JSFunctionResultCache::cast(caches->get(i))->Clear();
9887ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      }
989ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org    }
990e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Get the next context:
991e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
992ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  }
993ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org}
994ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
995ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
99665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgvoid Heap::ClearNormalizedMapCaches() {
997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (isolate_->bootstrapper()->IsActive() &&
998c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !incremental_marking()->IsMarking()) {
999c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return;
1000c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
10014a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
10023c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Object* context = native_contexts_list();
10034a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  while (!context->IsUndefined()) {
10047ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    // GC can happen when the context is not fully initialized,
10057ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    // so the cache can be undefined.
10067ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    Object* cache =
10077ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX);
10087ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    if (!cache->IsUndefined()) {
10097ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      NormalizedMapCache::cast(cache)->Clear();
10107ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    }
10114a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
10124a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  }
101365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
101465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
101565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
10167e6132b924829c353864933f29124419916db550machenbach@chromium.orgvoid Heap::UpdateSurvivalStatistics(int start_new_space_size) {
1017b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (start_new_space_size == 0) return;
1018b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
10193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  promotion_rate_ = (static_cast<double>(promoted_objects_size_) /
10203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                     static_cast<double>(start_new_space_size) * 100);
10216a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
10226a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  semi_space_copied_rate_ =
10233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      (static_cast<double>(semi_space_copied_object_size_) /
10243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org       static_cast<double>(start_new_space_size) * 100);
10256a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
10266a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  double survival_rate = promotion_rate_ + semi_space_copied_rate_;
102740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
1028659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (survival_rate > kYoungSurvivalRateHighThreshold) {
102940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org    high_survival_rate_period_length_++;
103040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  } else {
103140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org    high_survival_rate_period_length_ = 0;
103240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  }
103340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org}
103430ce411529579186181838984710b0b0980857aaricow@chromium.org
10354ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.orgbool Heap::PerformGarbageCollection(
10363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) {
1037c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  int freed_global_handles = 0;
1038f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
10394a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  if (collector != SCAVENGER) {
1040ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    PROFILE(isolate_, CodeMovingGCEvent());
10414a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  }
10424a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
1043c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
1044394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
1045c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    VerifyStringTable(this);
1046394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
1047c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
1048c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
10495d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  GCType gc_type =
10505d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge;
10515d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
10523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
10533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCCallbacksScope scope(this);
10542904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    if (scope.CheckReenter()) {
10552904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      AllowHeapAllocation allow_allocation;
1056474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
10572904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      VMState<EXTERNAL> state(isolate_);
10582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      HandleScope handle_scope(isolate_);
10592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags);
10602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
10615d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
10625d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
1063add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org  EnsureFromSpaceIsCommitted();
1064ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
1065f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  int start_new_space_size = Heap::new_space()->SizeAsInt();
106640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
1067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (IsHighSurvivalRate()) {
1068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // We speed up the incremental marker if it is running so that it
1069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // does not fall behind the rate of promotion, which would cause a
1070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // constantly growing old space.
1071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    incremental_marking()->NotifyOfHighPromotionRate();
1072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (collector == MARK_COMPACTOR) {
1075b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    // Perform mark-sweep with optional compaction.
1076474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    MarkCompact();
1077ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    sweep_generation_++;
1078c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    // Temporarily set the limit for case when PostGarbageCollectionProcessing
1079c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    // allocates and triggers GC. The real limit is set at after
1080c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    // PostGarbageCollectionProcessing.
1081a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    old_generation_allocation_limit_ =
1082c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org        OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0);
1083303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    old_gen_exhausted_ = false;
1084b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  } else {
1085b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    Scavenge();
108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1087439e85a92a8f3544428743c458d4941ad6deb1c2ager@chromium.org
10887e6132b924829c353864933f29124419916db550machenbach@chromium.org  UpdateSurvivalStatistics(start_new_space_size);
10891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
1090ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->counters()->objs_since_last_young()->Set(0);
109143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
109283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Callbacks that fire after this point might trigger nested GCs and
109383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // restart incremental marking, the assertion can't be moved down.
1094e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(collector == SCAVENGER || incremental_marking()->IsStopped());
109583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
1096d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  gc_post_processing_depth_++;
10973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
10983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllowHeapAllocation allow_allocation;
1099474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
1100c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    freed_global_handles =
110193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        isolate_->global_handles()->PostGarbageCollectionProcessing(collector);
1102303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
1103d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  gc_post_processing_depth_--;
1104303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
1105594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  isolate_->eternal_handles()->PostGarbageCollectionProcessing(this);
1106594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
11073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Update relocatables.
11083d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Relocatable::PostGarbageCollectionProcessing(isolate_);
110943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11107276f14ca716596e0a0d17539516370c1f453847kasper.lund  if (collector == MARK_COMPACTOR) {
11117276f14ca716596e0a0d17539516370c1f453847kasper.lund    // Register the amount of external allocated memory.
11127276f14ca716596e0a0d17539516370c1f453847kasper.lund    amount_of_external_allocated_memory_at_last_global_gc_ =
11137276f14ca716596e0a0d17539516370c1f453847kasper.lund        amount_of_external_allocated_memory_;
11143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    old_generation_allocation_limit_ = OldGenerationAllocationLimit(
11153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        PromotedSpaceSizeOfObjects(), freed_global_handles);
11167276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
11177276f14ca716596e0a0d17539516370c1f453847kasper.lund
11183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
11193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCCallbacksScope scope(this);
11202904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    if (scope.CheckReenter()) {
11212904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      AllowHeapAllocation allow_allocation;
1122474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
11232904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      VMState<EXTERNAL> state(isolate_);
11242904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      HandleScope handle_scope(isolate_);
11252904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      CallGCEpilogueCallbacks(gc_type, gc_callback_flags);
11262904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
112743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1128c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
1129c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
1130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
1131c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    VerifyStringTable(this);
1132394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
1133c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
1134f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1135c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  return freed_global_handles > 0;
113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1139ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) {
1140003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
1141003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    if (gc_type & gc_prologue_callbacks_[i].gc_type) {
1142528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      if (!gc_prologue_callbacks_[i].pass_isolate_) {
1143528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        v8::GCPrologueCallback callback =
1144528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org            reinterpret_cast<v8::GCPrologueCallback>(
1145528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                gc_prologue_callbacks_[i].callback);
1146528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        callback(gc_type, flags);
1147528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      } else {
1148528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1149528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        gc_prologue_callbacks_[i].callback(isolate, gc_type, flags);
1150528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      }
1151003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
1152003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
1153003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
1154003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1155003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
11564ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.orgvoid Heap::CallGCEpilogueCallbacks(GCType gc_type,
11574ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org                                   GCCallbackFlags gc_callback_flags) {
1158003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
1159003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    if (gc_type & gc_epilogue_callbacks_[i].gc_type) {
1160528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      if (!gc_epilogue_callbacks_[i].pass_isolate_) {
1161528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        v8::GCPrologueCallback callback =
1162528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org            reinterpret_cast<v8::GCPrologueCallback>(
1163528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                gc_epilogue_callbacks_[i].callback);
11644ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org        callback(gc_type, gc_callback_flags);
1165528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      } else {
1166528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
11673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        gc_epilogue_callbacks_[i].callback(isolate, gc_type, gc_callback_flags);
1168528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      }
1169003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
1170003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
1171003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
1172003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1173003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1174474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgvoid Heap::MarkCompact() {
117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  gc_state_ = MARK_COMPACT;
1176ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, ResourceEvent("markcompact", "begin"));
117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1178034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  uint64_t size_of_objects_before_gc = SizeOfObjects();
1179034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
1180474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  mark_compact_collector_.Prepare();
1181061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
1182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ms_count_++;
11832356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
1184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkCompactPrologue();
118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1186ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  mark_compact_collector_.CollectGarbage();
118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1188ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, ResourceEvent("markcompact", "end"));
118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  gc_state_ = NOT_IN_GC;
119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1192ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->counters()->objs_since_last_full()->Set(0);
11938b2bb2665b37457fd2bdccbce0356051c83a73fckasperl@chromium.org
1194c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  flush_monomorphic_ics_ = false;
1195034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
1196034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  if (FLAG_allocation_site_pretenuring) {
1197034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    EvaluateOldSpaceLocalPretenuring(size_of_objects_before_gc);
1198034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  }
119943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::MarkCompactPrologue() {
1203061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  // At any old GC clear the keyed lookup cache to enable collection of unused
1204061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  // maps.
1205ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->keyed_lookup_cache()->Clear();
1206ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->context_slot_cache()->Clear();
1207ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->descriptor_lookup_cache()->Clear();
120878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  RegExpResultsCache::Clear(string_split_cache());
120978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  RegExpResultsCache::Clear(regexp_multiple_cache());
1210061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
1211ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->compilation_cache()->MarkCompactPrologue();
1212061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
1213720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  CompletelyClearInstanceofCache();
1214720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
1215fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  FlushNumberStringCache();
1216e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  if (FLAG_cleanup_code_caches_at_gc) {
1217e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    polymorphic_code_cache()->set_cache(undefined_value());
1218e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
121965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
122065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ClearNormalizedMapCaches();
122143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
122243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
122343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper class for copying HeapObjects
12253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass ScavengeVisitor : public ObjectVisitor {
122643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
1227ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit ScavengeVisitor(Heap* heap) : heap_(heap) {}
122843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12295a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  void VisitPointer(Object** p) { ScavengePointer(p); }
123043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void VisitPointers(Object** start, Object** end) {
123243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Copy all HeapObject pointers in [start, end)
12335a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    for (Object** p = start; p < end; p++) ScavengePointer(p);
123443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
123543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
12375a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  void ScavengePointer(Object** p) {
12385a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    Object* object = *p;
1239ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (!heap_->InNewSpace(object)) return;
12405a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p),
12415a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                         reinterpret_cast<HeapObject*>(object));
124243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1244ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap_;
1245b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org};
1246b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1247b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1248c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
12499258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// Visitor class to verify pointers in code or data space do not point into
125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// new space.
12513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass VerifyNonPointerSpacePointersVisitor : public ObjectVisitor {
125243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
1253c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  explicit VerifyNonPointerSpacePointersVisitor(Heap* heap) : heap_(heap) {}
12543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  void VisitPointers(Object** start, Object** end) {
125543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (Object** current = start; current < end; current++) {
125643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if ((*current)->IsHeapObject()) {
1257c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org        CHECK(!heap_->InNewSpace(HeapObject::cast(*current)));
125843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
125943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
126043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1261c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
1262c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org private:
1263c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Heap* heap_;
126443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
12659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
1266b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1267c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgstatic void VerifyNonPointerSpacePointers(Heap* heap) {
1268b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // Verify that there are no pointers to new space in spaces where we
1269b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // do not expect them.
1270c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  VerifyNonPointerSpacePointersVisitor v(heap);
1271c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  HeapObjectIterator code_it(heap->code_space());
12723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (HeapObject* object = code_it.Next(); object != NULL;
12733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org       object = code_it.Next())
12742bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com    object->Iterate(&v);
1275b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1276c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    HeapObjectIterator data_it(heap->old_data_space());
12773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    for (HeapObject* object = data_it.Next(); object != NULL;
12783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         object = data_it.Next())
1279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      object->Iterate(&v);
1280b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org}
1281c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif  // VERIFY_HEAP
1282b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1283defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
1284b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.orgvoid Heap::CheckNewSpaceExpansionCriteria() {
1285a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
1286a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      survived_since_last_expansion_ > new_space_.TotalCapacity()) {
12871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Grow the size of new space if there is room to grow, enough data
12881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // has survived scavenge since the last expansion and we are not in
12891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // high promotion mode.
1290b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    new_space_.Grow();
1291b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    survived_since_last_expansion_ = 0;
1292b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
1293b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
1294b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1295b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1296c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgstatic bool IsUnscavengedHeapObject(Heap* heap, Object** p) {
1297c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  return heap->InNewSpace(*p) &&
12983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         !HeapObject::cast(*p)->map_word().IsForwardingAddress();
1299c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org}
1300c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1301c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
13023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid Heap::ScavengeStoreBufferCallback(Heap* heap, MemoryChunk* page,
13033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                       StoreBufferEvent event) {
1304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap->store_buffer_rebuilder_.Callback(page, event);
1305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
1306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBufferRebuilder::Callback(MemoryChunk* page, StoreBufferEvent event) {
1309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (event == kStoreBufferStartScanningPagesEvent) {
1310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    start_of_current_page_ = NULL;
1311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    current_page_ = NULL;
1312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (event == kStoreBufferScanningPageEvent) {
1313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (current_page_ != NULL) {
1314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // If this page already overflowed the store buffer during this iteration.
1315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (current_page_->scan_on_scavenge()) {
1316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Then we should wipe out the entries that have been added for it.
1317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        store_buffer_->SetTop(start_of_current_page_);
1318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else if (store_buffer_->Top() - start_of_current_page_ >=
1319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 (store_buffer_->Limit() - store_buffer_->Top()) >> 2) {
1320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Did we find too many pointers in the previous page?  The heuristic is
1321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // that no page can take more then 1/5 the remaining slots in the store
1322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // buffer.
1323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        current_page_->set_scan_on_scavenge(true);
1324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        store_buffer_->SetTop(start_of_current_page_);
1325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else {
1326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // In this case the page we scanned took a reasonable number of slots in
1327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // the store buffer.  It has now been rehabilitated and is no longer
1328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // marked scan_on_scavenge.
1329e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(!current_page_->scan_on_scavenge());
1330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
1331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
1332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    start_of_current_page_ = store_buffer_->Top();
1333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    current_page_ = page;
1334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (event == kStoreBufferFullEvent) {
1335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The current page overflowed the store buffer again.  Wipe out its entries
1336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // in the store buffer and mark it scan-on-scavenge again.  This may happen
1337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // several times while scanning.
1338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (current_page_ == NULL) {
1339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Store Buffer overflowed while scanning promoted objects.  These are not
1340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // in any particular page, though they are likely to be clustered by the
1341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // allocation routines.
134241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      store_buffer_->EnsureSpace(StoreBuffer::kStoreBufferSize / 2);
1343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
1344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Store Buffer overflowed while scanning a particular old space page for
1345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // pointers to new space.
1346e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(current_page_ == page);
1347e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(page != NULL);
1348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current_page_->set_scan_on_scavenge(true);
1349e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(start_of_current_page_ != store_buffer_->Top());
1350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      store_buffer_->SetTop(start_of_current_page_);
1351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
1352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
1353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    UNREACHABLE();
1354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
1356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1358c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgvoid PromotionQueue::Initialize() {
1359c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // Assumes that a NewSpacePage exactly fits a number of promotion queue
1360c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // entries (where each is a pair of intptr_t). This allows us to simplify
1361c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // the test fpr when to switch pages.
13623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) ==
13633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         0);
1364c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  limit_ = reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceStart());
1365c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  front_ = rear_ =
1366c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceEnd());
1367c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  emergency_stack_ = NULL;
1368c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org}
1369c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1370c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1371c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgvoid PromotionQueue::RelocateQueueHead() {
1372e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(emergency_stack_ == NULL);
1373c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1374c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Page* p = Page::FromAllocationTop(reinterpret_cast<Address>(rear_));
1375c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  intptr_t* head_start = rear_;
13763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  intptr_t* head_end = Min(front_, reinterpret_cast<intptr_t*>(p->area_end()));
1377c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1378c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int entries_count =
1379c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      static_cast<int>(head_end - head_start) / kEntrySizeInWords;
1380c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1381c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  emergency_stack_ = new List<Entry>(2 * entries_count);
1382c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1383c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  while (head_start != head_end) {
1384c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    int size = static_cast<int>(*(head_start++));
1385c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    HeapObject* obj = reinterpret_cast<HeapObject*>(*(head_start++));
1386c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    emergency_stack_->Add(Entry(obj, size));
1387c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  }
1388c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  rear_ = head_end;
1389c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org}
1390c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1391c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1392ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comclass ScavengeWeakObjectRetainer : public WeakObjectRetainer {
1393ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com public:
13943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  explicit ScavengeWeakObjectRetainer(Heap* heap) : heap_(heap) {}
1395ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1396ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  virtual Object* RetainAs(Object* object) {
1397ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (!heap_->InFromSpace(object)) {
1398ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      return object;
1399ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
1400ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1401ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    MapWord map_word = HeapObject::cast(object)->map_word();
1402ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (map_word.IsForwardingAddress()) {
1403ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      return map_word.ToForwardingAddress();
1404ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
1405ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    return NULL;
1406ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
1407ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1408ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com private:
1409ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  Heap* heap_;
1410ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com};
1411ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1412ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1413b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgvoid Heap::Scavenge() {
1414ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  RelocationLock relocation_lock(this);
1415ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1416c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
1417c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  if (FLAG_verify_heap) VerifyNonPointerSpacePointers(this);
141843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
141943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
142043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  gc_state_ = SCAVENGE;
142143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Implements Cheney's copying algorithm
1423ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, ResourceEvent("scavenge", "begin"));
142443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14255aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Clear descriptor cache.
1426ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->descriptor_lookup_cache()->Clear();
14275aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
1428eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Used for updating survived_since_last_expansion_ at function end.
1429659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  intptr_t survived_watermark = PromotedSpaceSizeOfObjects();
1430eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SelectScavengingVisitorsTable();
1432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  incremental_marking()->PrepareForScavenge();
1434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
143543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Flip the semispaces.  After flipping, to space is empty, from space has
143643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // live objects.
14375a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  new_space_.Flip();
14385a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  new_space_.ResetAllocationInfo();
143943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1440b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // We need to sweep newly copied objects which can be either in the
1441b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // to space or promoted to the old generation.  For to-space
1442b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // objects, we treat the bottom of the to space as a queue.  Newly
1443b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // copied and unswept objects lie between a 'front' mark and the
1444b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // allocation pointer.
1445b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  //
1446b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // Promoted objects can go into various old-generation spaces, and
1447b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // can be allocated internally in the spaces (from the free list).
1448b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // We treat the top of the to space as a queue of addresses of
1449b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // promoted objects.  The addresses of newly promoted and unswept
1450b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // objects lie between a 'front' mark and a 'rear' mark that is
1451b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // updated as a side effect of promoting an object.
145243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
1453b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // There is guaranteed to be enough room at the top of the to space
1454b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // for the addresses of promoted objects: every object promoted
1455b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // frees up its size in bytes from the top of the new space, and
1456b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  // objects are at least one pointer in size.
1457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address new_space_front = new_space_.ToSpaceStart();
1458c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  promotion_queue_.Initialize();
1459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG
1461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->Clean();
1462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
146343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1464ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ScavengeVisitor scavenge_visitor(this);
146543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Copy roots.
146613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE);
1467b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
1468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Copy objects reachable from the old generation.
1469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
14703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    StoreBufferRebuildScope scope(this, store_buffer(),
1471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  &ScavengeStoreBufferCallback);
1472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    store_buffer()->IteratePointersToNewSpace(&ScavengeObject);
1473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1474defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
147541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Copy objects reachable from simple cells by scavenging cell values
147641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // directly.
1477defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  HeapObjectIterator cell_iterator(cell_space_);
14783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (HeapObject* heap_object = cell_iterator.Next(); heap_object != NULL;
1479000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org       heap_object = cell_iterator.Next()) {
148041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (heap_object->IsCell()) {
148141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Cell* cell = Cell::cast(heap_object);
148241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Address value_address = cell->ValueAddress();
148341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
148441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
148541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
148641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
148741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Copy objects reachable from global property cells by scavenging global
148841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // property cell values directly.
148941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  HeapObjectIterator js_global_property_cell_iterator(property_cell_space_);
149041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  for (HeapObject* heap_object = js_global_property_cell_iterator.Next();
149141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org       heap_object != NULL;
149241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org       heap_object = js_global_property_cell_iterator.Next()) {
1493b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (heap_object->IsPropertyCell()) {
1494b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      PropertyCell* cell = PropertyCell::cast(heap_object);
1495000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org      Address value_address = cell->ValueAddress();
1496defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
149741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Address type_address = cell->TypeAddress();
149841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(type_address));
1499defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    }
1500defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  }
150143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1502196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // Copy objects reachable from the encountered weak collections list.
1503196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  scavenge_visitor.VisitPointer(&encountered_weak_collections_);
1504196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
1505e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Copy objects reachable from the code flushing candidates list.
1506e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  MarkCompactCollector* collector = mark_compact_collector();
1507e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (collector->is_code_flushing_enabled()) {
1508e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor);
1509e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
1510e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
151113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1512e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
151349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  while (isolate()->global_handles()->IterateObjectGroups(
151449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      &scavenge_visitor, &IsUnscavengedHeapObject)) {
1515e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1516e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
1517e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  isolate()->global_handles()->RemoveObjectGroups();
1518003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  isolate()->global_handles()->RemoveImplicitRefGroups();
1519e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1520e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
1521c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      &IsUnscavengedHeapObject);
1522e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
1523e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      &scavenge_visitor);
1524c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1525c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1526b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  UpdateNewSpaceReferencesInExternalStringTable(
1527b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org      &UpdateNewSpaceReferenceInExternalStringTableEntry);
1528b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1529c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  promotion_queue_.Destroy();
1530c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  incremental_marking()->UpdateMarkingDequeAfterScavenge();
15320ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
1533ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  ScavengeWeakObjectRetainer weak_object_retainer(this);
1534ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  ProcessWeakReferences(&weak_object_retainer);
1535ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1536e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(new_space_front == new_space_.top());
153713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
153813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Set age mark.
153913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  new_space_.set_age_mark(new_space_.top());
154013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  new_space_.LowerInlineAllocationLimit(
1542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      new_space_.inline_allocation_limit_step());
1543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
154413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Update how much has survived scavenge.
1545f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  IncrementYoungSurvivorsCounter(static_cast<int>(
1546659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size()));
154713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1548ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, ResourceEvent("scavenge", "end"));
154913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
155013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  gc_state_ = NOT_IN_GC;
15519865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org
15529865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org  gc_idle_time_handler_.NotifyScavenge();
155313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
155413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
155513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1556ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgString* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
1557ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                                Object** p) {
1558b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  MapWord first_word = HeapObject::cast(*p)->map_word();
1559b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1560b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  if (!first_word.IsForwardingAddress()) {
1561b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    // Unreachable external string can be finalized.
1562ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    heap->FinalizeExternalString(String::cast(*p));
1563b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    return NULL;
1564b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
1565b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1566b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  // String is still reachable.
1567b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  return String::cast(first_word.ToForwardingAddress());
1568b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
1569b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1570b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
1571b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.orgvoid Heap::UpdateNewSpaceReferencesInExternalStringTable(
1572b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    ExternalStringTableUpdaterCallback updater_func) {
1573c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
1574394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
1575394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    external_string_table_.Verify();
1576394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
1577c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
157813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1579ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (external_string_table_.new_space_strings_.is_empty()) return;
158013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
15812ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  Object** start = &external_string_table_.new_space_strings_[0];
15822ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  Object** end = start + external_string_table_.new_space_strings_.length();
15832ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  Object** last = start;
158413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
15852ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  for (Object** p = start; p < end; ++p) {
1586e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(InFromSpace(*p));
1587ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    String* target = updater_func(this, p);
158813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1589b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    if (target == NULL) continue;
159013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1591e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(target->IsExternalString());
159213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1593ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (InNewSpace(target)) {
159413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      // String is still in new space.  Update the table entry.
159513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      *last = target;
159613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      ++last;
159713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    } else {
159813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      // String got promoted.  Move it to the old string list.
1599ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      external_string_table_.AddOldString(target);
160013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    }
160113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
160213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1603e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(last <= end);
16042ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  external_string_table_.ShrinkNewStrings(static_cast<int>(last - start));
160513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
160613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
160713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1608c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::UpdateReferencesInExternalStringTable(
1609c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ExternalStringTableUpdaterCallback updater_func) {
1610c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Update old space string references.
1611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (external_string_table_.old_space_strings_.length() > 0) {
16122ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    Object** start = &external_string_table_.old_space_strings_[0];
16132ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    Object** end = start + external_string_table_.old_space_strings_.length();
16142ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    for (Object** p = start; p < end; ++p) *p = updater_func(this, p);
1615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  UpdateNewSpaceReferencesInExternalStringTable(updater_func);
1618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
1619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
16214a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
16221e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  ProcessArrayBuffers(retainer);
16231e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  ProcessNativeContexts(retainer);
1624af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // TODO(mvstanton): AllocationSites only need to be processed during
1625af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // MARK_COMPACT, as they live in old space. Verify and address.
16261e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  ProcessAllocationSites(retainer);
16271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
16281fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
16291e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org
16301e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgvoid Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) {
16311e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  Object* head = VisitWeakList<Context>(this, native_contexts_list(), retainer);
16324a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  // Update the head of the list of contexts.
16333c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  set_native_contexts_list(head);
16344a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org}
16354a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
16364a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
16371e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgvoid Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer) {
16381fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  Object* array_buffer_obj =
16391e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org      VisitWeakList<JSArrayBuffer>(this, array_buffers_list(), retainer);
16401fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_array_buffers_list(array_buffer_obj);
16411fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
16421fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
16431fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
16441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Heap::TearDownArrayBuffers() {
16451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Object* undefined = undefined_value();
16461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  for (Object* o = array_buffers_list(); o != undefined;) {
16471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    JSArrayBuffer* buffer = JSArrayBuffer::cast(o);
16481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Runtime::FreeArrayBuffer(isolate(), buffer);
16491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    o = buffer->weak_next();
16501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
16513c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  set_array_buffers_list(undefined);
16521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
16531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
16541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
16551e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgvoid Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) {
1656ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Object* allocation_site_obj =
16571e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org      VisitWeakList<AllocationSite>(this, allocation_sites_list(), retainer);
1658ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  set_allocation_sites_list(allocation_site_obj);
1659ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
1660ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1661ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1662034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.orgvoid Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) {
16635c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  DisallowHeapAllocation no_allocation_scope;
1664034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  Object* cur = allocation_sites_list();
16655c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  bool marked = false;
1666034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  while (cur->IsAllocationSite()) {
1667034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    AllocationSite* casted = AllocationSite::cast(cur);
1668034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    if (casted->GetPretenureMode() == flag) {
1669034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      casted->ResetPretenureDecision();
1670f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      casted->set_deopt_dependent_code(true);
1671f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      marked = true;
1672034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    }
1673034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    cur = casted->weak_next();
1674034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  }
16753c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (marked) isolate_->stack_guard()->RequestDeoptMarkedAllocationSites();
1676034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org}
1677034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
1678034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
1679034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.orgvoid Heap::EvaluateOldSpaceLocalPretenuring(
1680034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    uint64_t size_of_objects_before_gc) {
1681034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  uint64_t size_of_objects_after_gc = SizeOfObjects();
1682034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  double old_generation_survival_rate =
1683034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      (static_cast<double>(size_of_objects_after_gc) * 100) /
16843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      static_cast<double>(size_of_objects_before_gc);
1685034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
1686034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  if (old_generation_survival_rate < kOldSurvivalRateLowThreshold) {
1687034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    // Too many objects died in the old generation, pretenuring of wrong
1688034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    // allocation sites may be the cause for that. We have to deopt all
1689034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    // dependent code registered in the allocation sites to re-evaluate
1690034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    // our pretenuring decisions.
1691034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    ResetAllAllocationSitesDependentCode(TENURED);
1692034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    if (FLAG_trace_pretenuring) {
16933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      PrintF(
16943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          "Deopt all allocation sites dependent code due to low survival "
16953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          "rate in the old generation %f\n",
16963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          old_generation_survival_rate);
1697034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    }
1698034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  }
1699034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org}
1700034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
1701034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
1702f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
170379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
1704113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  // All external strings are listed in the external string table.
1705e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1706e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  class ExternalStringTableVisitorAdapter : public ObjectVisitor {
1707f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com   public:
1708e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    explicit ExternalStringTableVisitorAdapter(
17093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        v8::ExternalResourceVisitor* visitor)
17103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        : visitor_(visitor) {}
1711e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    virtual void VisitPointers(Object** start, Object** end) {
1712e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      for (Object** p = start; p < end; p++) {
1713e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK((*p)->IsExternalString());
17143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        visitor_->VisitExternalString(
17153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            Utils::ToLocal(Handle<String>(String::cast(*p))));
1716e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      }
1717e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
17183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
1719e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org   private:
1720e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    v8::ExternalResourceVisitor* visitor_;
1721e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } external_string_table_visitor(visitor);
1722e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1723e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  external_string_table_.Iterate(&external_string_table_visitor);
1724f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
1725f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
1726f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
1727ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> {
1728ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
1729ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static inline void VisitPointer(Heap* heap, Object** p) {
1730ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    Object* object = *p;
1731ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (!heap->InNewSpace(object)) return;
1732ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p),
1733ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                         reinterpret_cast<HeapObject*>(object));
1734ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
1735ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
1736ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1737ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
173813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgAddress Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
173913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                         Address new_space_front) {
1740b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  do {
1741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    SemiSpace::AssertValidRange(new_space_front, new_space_.top());
1742b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // The addresses new_space_front and new_space_.top() define a
1743b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // queue of unprocessed copied objects.  Process them until the
1744b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // queue is empty.
1745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    while (new_space_front != new_space_.top()) {
1746c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (!NewSpacePage::IsAtEnd(new_space_front)) {
1747c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        HeapObject* object = HeapObject::FromAddress(new_space_front);
1748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        new_space_front +=
17493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            NewSpaceScavenger::IterateBody(object->map(), object);
1750c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else {
1751c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        new_space_front =
1752ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org            NewSpacePage::FromLimit(new_space_front)->next_page()->area_start();
1753c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
1754b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    }
175543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1756b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // Promote and process all the to-be-promoted objects.
1757c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    {
17583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      StoreBufferRebuildScope scope(this, store_buffer(),
1759c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                    &ScavengeStoreBufferCallback);
1760c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      while (!promotion_queue()->is_empty()) {
1761c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        HeapObject* target;
1762c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        int size;
1763c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        promotion_queue()->remove(&target, &size);
1764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1765c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Promoted object might be already partially visited
1766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // during old space pointer iteration. Thus we search specificly
1767c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // for pointers to from semispace instead of looking for pointers
1768c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // to new space.
1769e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(!target->IsMap());
17703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        IterateAndMarkPointersToFromSpace(
17713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            target->address(), target->address() + size, &ScavengeObject);
1772c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
177343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
177443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1775b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // Take another spin if there are now unswept objects in new space
1776b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // (there are currently no more unswept promoted objects).
1777c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } while (new_space_front != new_space_.top());
177843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
177913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  return new_space_front;
178043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
178143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
178243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgSTATIC_ASSERT((FixedDoubleArray::kHeaderSize & kDoubleAlignmentMask) ==
17843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              0);  // NOLINT
17853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgSTATIC_ASSERT((ConstantPoolArray::kFirstEntryOffset & kDoubleAlignmentMask) ==
17863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              0);  // NOLINT
1787196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgSTATIC_ASSERT((ConstantPoolArray::kExtendedFirstOffset &
1788196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org               kDoubleAlignmentMask) == 0);  // NOLINT
1789ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1790ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
17913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgINLINE(static HeapObject* EnsureDoubleAligned(Heap* heap, HeapObject* object,
1792ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                                              int size));
1793ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
17943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic HeapObject* EnsureDoubleAligned(Heap* heap, HeapObject* object,
1795ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                                       int size) {
1796ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  if ((OffsetFrom(object->address()) & kDoubleAlignmentMask) != 0) {
1797ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    heap->CreateFillerObjectAt(object->address(), kPointerSize);
1798ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    return HeapObject::FromAddress(object->address() + kPointerSize);
1799ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  } else {
1800ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    heap->CreateFillerObjectAt(object->address() + size - kPointerSize,
1801ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                               kPointerSize);
1802ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    return object;
1803ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
1804ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com}
1805ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1806ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1807c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgenum LoggingAndProfiling {
1808c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  LOGGING_AND_PROFILING_ENABLED,
1809c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  LOGGING_AND_PROFILING_DISABLED
1810c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org};
1811c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
1812c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
1813c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS };
1814c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
1815c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
18163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <MarksHandling marks_handling,
18173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          LoggingAndProfiling logging_and_profiling_mode>
1818ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgclass ScavengingVisitor : public StaticVisitorBase {
1819ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org public:
1820ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  static void Initialize() {
1821fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString);
1822ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString);
1823ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate);
1824ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitByteArray, &EvacuateByteArray);
1825ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.Register(kVisitFixedArray, &EvacuateFixedArray);
18266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray);
18275c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    table_.Register(kVisitFixedTypedArray, &EvacuateFixedTypedArray);
18285c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    table_.Register(kVisitFixedFloat64Array, &EvacuateFixedFloat64Array);
1829c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
18303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    table_.Register(
18313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        kVisitNativeContext,
18323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized<
18333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            Context::kSize>);
183443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    table_.Register(
18363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        kVisitConsString,
18373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized<
18383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            ConsString::kSize>);
183943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    table_.Register(
18413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        kVisitSlicedString,
18423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized<
18433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            SlicedString::kSize>);
18444668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org
18453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    table_.Register(
18463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        kVisitSymbol,
18473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized<
18483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            Symbol::kSize>);
1849f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
18503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    table_.Register(
18513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        kVisitSharedFunctionInfo,
18523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized<
18533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            SharedFunctionInfo::kSize>);
185443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1855e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    table_.Register(kVisitJSWeakCollection,
18563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit);
1857ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
18581fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    table_.Register(kVisitJSArrayBuffer,
18593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit);
18601fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
18611fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    table_.Register(kVisitJSTypedArray,
18623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit);
18631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
18641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    table_.Register(kVisitJSDataView,
18653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit);
18661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1867ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    table_.Register(kVisitJSRegExp,
18683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                    &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit);
1869ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
1870c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (marks_handling == IGNORE_MARKS) {
18713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      table_.Register(
18723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          kVisitJSFunction,
18733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized<
18743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              JSFunction::kSize>);
1875c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
1876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      table_.Register(kVisitJSFunction, &EvacuateJSFunction);
1877c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
18780b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
1879ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>,
18803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   kVisitDataObject, kVisitDataObjectGeneric>();
188143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1882ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>,
18833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   kVisitJSObject, kVisitJSObjectGeneric>();
188443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1885ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>,
18863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   kVisitStruct, kVisitStructGeneric>();
1887ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
188843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1889c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  static VisitorDispatchTable<ScavengingCallback>* GetTable() {
1890c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return &table_;
1891ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
18926a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
1893ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org private:
18943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  enum ObjectContents { DATA_OBJECT, POINTER_OBJECT };
18956a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
1896ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static void RecordCopiedObject(Heap* heap, HeapObject* obj) {
1897ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    bool should_record = false;
1898ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org#ifdef DEBUG
1899ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    should_record = FLAG_heap_stats;
1900ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org#endif
1901ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    should_record = should_record || FLAG_log_gc;
1902ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    if (should_record) {
1903ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      if (heap->new_space()->Contains(obj)) {
1904ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        heap->new_space()->RecordAllocation(obj);
19056a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org      } else {
1906ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        heap->new_space()->RecordPromotion(obj);
19076a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org      }
19086a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    }
19096a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
19105a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
1911ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // Helper function used by CopyObject to copy a source object to an
1912ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // allocated target object and update the forwarding pointer in the source
1913ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  // object.  Returns the target object.
19143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  INLINE(static void MigrateObject(Heap* heap, HeapObject* source,
19153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   HeapObject* target, int size)) {
191658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    // If we migrate into to-space, then the to-space top pointer should be
191758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    // right after the target object. Incorporate double alignment
191858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    // over-allocation.
1919e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!heap->InToSpace(target) ||
19203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           target->address() + size == heap->new_space()->top() ||
19213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           target->address() + size + kPointerSize == heap->new_space()->top());
192258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org
192358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    // Make sure that we do not overwrite the promotion queue which is at
192458a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    // the end of to-space.
1925e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!heap->InToSpace(target) ||
19263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           heap->promotion_queue()->IsBelowPromotionQueue(
19273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org               heap->new_space()->top()));
192858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org
1929ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    // Copy the content of source to target.
1930ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    heap->CopyBlock(target->address(), source->address(), size);
19315a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
1932ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    // Set the forwarding address.
1933ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    source->set_map_word(MapWord::FromForwardingAddress(target));
19346a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
1935c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) {
1936c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      // Update NewSpace stats if necessary.
1937c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RecordCopiedObject(heap, target);
19384b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      heap->OnMoveEvent(target, source, size);
1939c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
1940c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
1941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (marks_handling == TRANSFER_MARKS) {
1942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (Marking::TransferColor(source, target)) {
19432efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        MemoryChunk::IncrementLiveBytesFromGC(target->address(), size);
1944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
1945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
1946ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
19476a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
19483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  template <int alignment>
19493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline bool SemiSpaceCopyObject(Map* map, HeapObject** slot,
19503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                         HeapObject* object, int object_size) {
1951c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    Heap* heap = map->GetHeap();
1952c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
1953c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    int allocation_size = object_size;
1954c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    if (alignment != kObjectAlignment) {
1955e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(alignment == kDoubleAlignment);
1956c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      allocation_size += kPointerSize;
1957c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    }
1958c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
1959e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(heap->AllowedToBeMigrated(object, NEW_SPACE));
1960c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    AllocationResult allocation =
1961c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org        heap->new_space()->AllocateRaw(allocation_size);
1962c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
1963c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    HeapObject* target = NULL;  // Initialization to please compiler.
1964c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    if (allocation.To(&target)) {
19652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      // Order is important here: Set the promotion limit before storing a
19662c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      // filler for double alignment or migrating the object. Otherwise we
19672c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      // may end up overwriting promotion queue entries when we migrate the
19682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      // object.
19692c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      heap->promotion_queue()->SetNewLimit(heap->new_space()->top());
19702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org
1971c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      if (alignment != kObjectAlignment) {
1972c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org        target = EnsureDoubleAligned(heap, target, allocation_size);
1973c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      }
1974c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
1975c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      // Order is important: slot might be inside of the target if target
1976c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      // was allocated over a dead object and slot comes from the store
1977c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      // buffer.
1978c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      *slot = target;
1979c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      MigrateObject(heap, object, target, object_size);
1980c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
1981c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      heap->IncrementSemiSpaceCopiedObjectSize(object_size);
1982c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      return true;
1983c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    }
1984c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    return false;
1985c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  }
1986c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
1987ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
19883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  template <ObjectContents object_contents, int alignment>
19893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline bool PromoteObject(Map* map, HeapObject** slot,
19903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   HeapObject* object, int object_size) {
1991c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    Heap* heap = map->GetHeap();
19926a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
1993ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    int allocation_size = object_size;
1994ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (alignment != kObjectAlignment) {
1995e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(alignment == kDoubleAlignment);
1996ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      allocation_size += kPointerSize;
1997ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
1998ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1999c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    AllocationResult allocation;
2000c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    if (object_contents == DATA_OBJECT) {
2001e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(heap->AllowedToBeMigrated(object, OLD_DATA_SPACE));
2002c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      allocation = heap->old_data_space()->AllocateRaw(allocation_size);
2003c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    } else {
2004e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(heap->AllowedToBeMigrated(object, OLD_POINTER_SPACE));
2005c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      allocation = heap->old_pointer_space()->AllocateRaw(allocation_size);
2006c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    }
20076a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2008c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    HeapObject* target = NULL;  // Initialization to please compiler.
2009c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    if (allocation.To(&target)) {
2010c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      if (alignment != kObjectAlignment) {
2011c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org        target = EnsureDoubleAligned(heap, target, allocation_size);
2012ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      }
20136a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2014c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      // Order is important: slot might be inside of the target if target
2015c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      // was allocated over a dead object and slot comes from the store
2016c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      // buffer.
2017c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      *slot = target;
2018c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      MigrateObject(heap, object, target, object_size);
2019c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
2020c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      if (object_contents == POINTER_OBJECT) {
2021c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org        if (map->instance_type() == JS_FUNCTION_TYPE) {
20223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          heap->promotion_queue()->insert(target,
20233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                          JSFunction::kNonWeakFieldsEndOffset);
2024c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org        } else {
2025c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org          heap->promotion_queue()->insert(target, object_size);
2026ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        }
2027c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      }
2028c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      heap->IncrementPromotedObjectsSize(object_size);
2029c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      return true;
2030c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    }
2031c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    return false;
2032c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  }
2033ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
20346a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
20353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  template <ObjectContents object_contents, int alignment>
20363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateObject(Map* map, HeapObject** slot,
20373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                    HeapObject* object, int object_size) {
2038e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    SLOW_DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
2039e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    SLOW_DCHECK(object->Size() == object_size);
2040c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    Heap* heap = map->GetHeap();
20416a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2042c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    if (!heap->ShouldBePromoted(object->address(), object_size)) {
2043c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      // A semi-space copy may fail due to fragmentation. In that case, we
2044c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      // try to promote the object.
2045c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) {
2046ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        return;
20476a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org      }
2048ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    }
2049c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
20503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (PromoteObject<object_contents, alignment>(map, slot, object,
20513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                  object_size)) {
2052c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      return;
2053ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
2054ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
2055c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    // If promotion failed, we try to copy the object to the other semi-space
2056c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) return;
2057c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
2058c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    UNREACHABLE();
2059ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
20606a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
20616a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
20623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateJSFunction(Map* map, HeapObject** slot,
2063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                        HeapObject* object) {
20643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized<
20653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        JSFunction::kSize>(map, slot, object);
2066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
206742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    MapWord map_word = object->map_word();
206842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    DCHECK(map_word.IsForwardingAddress());
206942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    HeapObject* target = map_word.ToForwardingAddress();
207042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org
2071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(target);
2072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (Marking::IsBlack(mark_bit)) {
2073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // This object is black and it might not be rescanned by marker.
2074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // We should explicitly record code entry slot for compaction because
2075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // promotion queue processing (IterateAndMarkPointersToFromSpace) will
2076c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // miss it as it is not HeapObject-tagged.
2077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Address code_entry_slot =
2078c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          target->address() + JSFunction::kCodeEntryOffset;
2079c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot));
20803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot(
20813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          code_entry_slot, code);
2082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
2083c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
2084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2085c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
20863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateFixedArray(Map* map, HeapObject** slot,
2087ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                        HeapObject* object) {
2088ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    int object_size = FixedArray::BodyDescriptor::SizeOf(map, object);
20893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    EvacuateObject<POINTER_OBJECT, kObjectAlignment>(map, slot, object,
20903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                     object_size);
20916a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
20926a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
20936a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
20943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateFixedDoubleArray(Map* map, HeapObject** slot,
20956d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                              HeapObject* object) {
20966d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
20976d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int object_size = FixedDoubleArray::SizeFor(length);
20983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    EvacuateObject<DATA_OBJECT, kDoubleAlignment>(map, slot, object,
20993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                  object_size);
21006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
21016d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
21026d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
21033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateFixedTypedArray(Map* map, HeapObject** slot,
21045c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org                                             HeapObject* object) {
21055c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size();
21063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object,
21073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                  object_size);
21085c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  }
21095c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
21105c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
21113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot,
21125c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org                                               HeapObject* object) {
21135c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size();
21143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    EvacuateObject<DATA_OBJECT, kDoubleAlignment>(map, slot, object,
21153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                  object_size);
21165c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  }
21175c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
21185c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
21193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateByteArray(Map* map, HeapObject** slot,
2120ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                       HeapObject* object) {
2121ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize();
21223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object,
21233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                  object_size);
2124ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
21256a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21266a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot,
21283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                              HeapObject* object) {
21293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    int object_size = SeqOneByteString::cast(object)
21303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                          ->SeqOneByteStringSize(map->instance_type());
21313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object,
21323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                  object_size);
2133ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
21346a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21356a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateSeqTwoByteString(Map* map, HeapObject** slot,
2137ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                              HeapObject* object) {
21383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    int object_size = SeqTwoByteString::cast(object)
21393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                          ->SeqTwoByteStringSize(map->instance_type());
21403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object,
21413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                  object_size);
2142ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
21436a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21445a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
21453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static inline void EvacuateShortcutCandidate(Map* map, HeapObject** slot,
2146ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                               HeapObject* object) {
2147e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsShortcutCandidate(map->instance_type()));
21486a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Heap* heap = map->GetHeap();
2150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (marks_handling == IGNORE_MARKS &&
21523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        ConsString::cast(object)->unchecked_second() == heap->empty_string()) {
2153ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      HeapObject* first =
2154ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org          HeapObject::cast(ConsString::cast(object)->unchecked_first());
21556a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2156ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      *slot = first;
21576a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (!heap->InNewSpace(first)) {
2159ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        object->set_map_word(MapWord::FromForwardingAddress(first));
2160ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        return;
2161ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      }
21626a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2163ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      MapWord first_word = first->map_word();
2164ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      if (first_word.IsForwardingAddress()) {
2165ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        HeapObject* target = first_word.ToForwardingAddress();
2166ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
2167ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        *slot = target;
2168ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        object->set_map_word(MapWord::FromForwardingAddress(target));
2169ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        return;
2170ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      }
2171ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
2172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      heap->DoScavengeObject(first->map(), slot, first);
2173ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      object->set_map_word(MapWord::FromForwardingAddress(*slot));
217443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
217543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
21766a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2177ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    int object_size = ConsString::kSize;
21783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    EvacuateObject<POINTER_OBJECT, kObjectAlignment>(map, slot, object,
21793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                     object_size);
218043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
218143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  template <ObjectContents object_contents>
2183ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  class ObjectEvacuationStrategy {
2184ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org   public:
21853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    template <int object_size>
21863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    static inline void VisitSpecialized(Map* map, HeapObject** slot,
2187ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                                        HeapObject* object) {
21883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      EvacuateObject<object_contents, kObjectAlignment>(map, slot, object,
21893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                        object_size);
219043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
21916a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
21923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    static inline void Visit(Map* map, HeapObject** slot, HeapObject* object) {
2193ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      int object_size = map->instance_size();
21943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      EvacuateObject<object_contents, kObjectAlignment>(map, slot, object,
21953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                        object_size);
2196ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    }
2197ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  };
21986a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2199c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  static VisitorDispatchTable<ScavengingCallback> table_;
2200ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
22016a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22026a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <MarksHandling marks_handling,
22043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          LoggingAndProfiling logging_and_profiling_mode>
2205c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgVisitorDispatchTable<ScavengingCallback>
2206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ScavengingVisitor<marks_handling, logging_and_profiling_mode>::table_;
2207c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2208c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2209c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgstatic void InitializeScavengingVisitorsTables() {
2210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ScavengingVisitor<TRANSFER_MARKS,
2211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                    LOGGING_AND_PROFILING_DISABLED>::Initialize();
2212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::Initialize();
2213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ScavengingVisitor<TRANSFER_MARKS,
2214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                    LOGGING_AND_PROFILING_ENABLED>::Initialize();
2215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize();
2216c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
2217c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2218c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::SelectScavengingVisitorsTable() {
2220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool logging_and_profiling =
22213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      FLAG_verify_predictable || isolate()->logger()->is_logging() ||
2222f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      isolate()->cpu_profiler()->is_profiling() ||
2223c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      (isolate()->heap_profiler() != NULL &&
2224cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org       isolate()->heap_profiler()->is_tracking_object_moves());
2225c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
2226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!incremental_marking()->IsMarking()) {
2227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!logging_and_profiling) {
22283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      scavenging_visitors_table_.CopyFrom(ScavengingVisitor<
22293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::GetTable());
2230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
22313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      scavenging_visitors_table_.CopyFrom(ScavengingVisitor<
22323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::GetTable());
2233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
2234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
2235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!logging_and_profiling) {
22363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      scavenging_visitors_table_.CopyFrom(ScavengingVisitor<
22373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          TRANSFER_MARKS, LOGGING_AND_PROFILING_DISABLED>::GetTable());
2238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
22393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      scavenging_visitors_table_.CopyFrom(ScavengingVisitor<
22403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          TRANSFER_MARKS, LOGGING_AND_PROFILING_ENABLED>::GetTable());
2241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
2242a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
2243a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    if (incremental_marking()->IsCompacting()) {
2244a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      // When compacting forbid short-circuiting of cons-strings.
2245a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      // Scavenging code relies on the fact that new space object
2246a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      // can't be evacuated into evacuation candidate but
2247a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      // short-circuiting violates this assumption.
2248a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      scavenging_visitors_table_.Register(
2249a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org          StaticVisitorBase::kVisitShortcutCandidate,
2250a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org          scavenging_visitors_table_.GetVisitorById(
2251a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org              StaticVisitorBase::kVisitConsString));
2252a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    }
2253c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
2254c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
22556a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22566a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22576a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgvoid Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) {
2258e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  SLOW_DCHECK(object->GetIsolate()->heap()->InFromSpace(object));
22596a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  MapWord first_word = object->map_word();
2260e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  SLOW_DCHECK(!first_word.IsForwardingAddress());
22616a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  Map* map = first_word.ToMap();
2262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  map->GetHeap()->DoScavengeObject(map, p, object);
22635a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
22645a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
22655a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
2266a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
2267a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                          int instance_size) {
2268303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
2269a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE);
2270a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&result)) return allocation;
227143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
227243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Map::cast cannot be used due to uninitialized map field.
227368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map());
227443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reinterpret_cast<Map*>(result)->set_instance_type(instance_type);
227543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reinterpret_cast<Map*>(result)->set_instance_size(instance_size);
2276ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  reinterpret_cast<Map*>(result)->set_visitor_id(
22773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      StaticVisitorBase::GetVisitorId(instance_type, instance_size));
22787c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  reinterpret_cast<Map*>(result)->set_inobject_properties(0);
2279b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  reinterpret_cast<Map*>(result)->set_pre_allocated_property_fields(0);
228043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
2281b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  reinterpret_cast<Map*>(result)->set_bit_field(0);
2282b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  reinterpret_cast<Map*>(result)->set_bit_field2(0);
2283af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
228406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org                   Map::OwnsDescriptors::encode(true);
228506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3);
228643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
228743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
228843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
228943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2290a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateMap(InstanceType instance_type,
2291a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                   int instance_size,
2292a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                   ElementsKind elements_kind) {
2293a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
2294a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE);
2295a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&result)) return allocation;
229643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2297a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(meta_map());
2298a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  Map* map = Map::cast(result);
229943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map->set_instance_type(instance_type);
2300ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  map->set_visitor_id(
2301ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      StaticVisitorBase::GetVisitorId(instance_type, instance_size));
230227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  map->set_prototype(null_value(), SKIP_WRITE_BARRIER);
230327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  map->set_constructor(null_value(), SKIP_WRITE_BARRIER);
230443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map->set_instance_size(instance_size);
23057c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  map->set_inobject_properties(0);
2306911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  map->set_pre_allocated_property_fields(0);
230727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
23082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  map->set_dependent_code(DependentCode::cast(empty_fixed_array()),
23092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                          SKIP_WRITE_BARRIER);
231081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  map->init_back_pointer(undefined_value());
231143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map->set_unused_property_fields(0);
231289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  map->set_instance_descriptors(empty_descriptor_array());
231343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map->set_bit_field(0);
2314d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  map->set_bit_field2(1 << Map::kIsExtensible);
2315af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
231606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org                   Map::OwnsDescriptors::encode(true);
2317355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  map->set_bit_field3(bit_field3);
2318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  map->set_elements_kind(elements_kind);
2319846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org
232043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return map;
232143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
232243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
232343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgAllocationResult Heap::AllocateFillerObject(int size, bool double_align,
2325a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                            AllocationSpace space) {
2326a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* obj;
23273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
23283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, space);
2329a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return allocation;
23308496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  }
23318496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org#ifdef DEBUG
2332a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
2333e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(chunk->owner()->identity() == space);
23348496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org#endif
2335a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  CreateFillerObjectAt(obj->address(), size);
2336a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  return obj;
23378496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org}
23388496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
23398496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
234068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgconst Heap::StringTypeTable Heap::string_type_table[] = {
23413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
23423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  { type, size, k##camel_name##MapRootIndex }             \
23433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  ,
23443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    STRING_TYPE_LIST(STRING_TYPE_ELEMENT)
234568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org#undef STRING_TYPE_ELEMENT
234668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org};
234768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
234868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
23494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgconst Heap::ConstantStringTable Heap::constant_string_table[] = {
23503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define CONSTANT_STRING_ELEMENT(name, contents) \
23513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  { contents, k##name##RootIndex }              \
23523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  ,
23533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT)
23544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org#undef CONSTANT_STRING_ELEMENT
235568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org};
235668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
235768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
235868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgconst Heap::StructTable Heap::struct_table[] = {
23593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define STRUCT_TABLE_ELEMENT(NAME, Name, name)        \
23603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex } \
23613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  ,
23623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    STRUCT_LIST(STRUCT_TABLE_ELEMENT)
236368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org#undef STRUCT_TABLE_ELEMENT
236468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org};
236568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
236668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
236743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::CreateInitialMaps() {
2368a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* obj;
23693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
23703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize);
2371a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return false;
2372303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
237343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Map::cast cannot be used due to uninitialized map field.
237468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  Map* new_meta_map = reinterpret_cast<Map*>(obj);
237568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_meta_map(new_meta_map);
237668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  new_meta_map->set_map(new_meta_map);
237743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23781e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  {  // Partial map allocation
23793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name)                \
23803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {                                                                          \
23813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Map* map;                                                                \
23823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (!AllocatePartialMap((instance_type), (size)).To(&map)) return false; \
23833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    set_##field_name##_map(map);                                             \
23843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
238543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
238649ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array);
238749ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined);
238849ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null);
238949ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_PARTIAL_MAP(CONSTANT_POOL_ARRAY_TYPE, kVariableSizeSentinel,
239049ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org                         constant_pool_array);
239143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
239249ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org#undef ALLOCATE_PARTIAL_MAP
23939ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  }
23949ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
23955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Allocate the empty array.
23963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
23973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateEmptyFixedArray();
2398a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return false;
2399303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
240068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  set_empty_fixed_array(FixedArray::cast(obj));
240143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
24033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = Allocate(null_map(), OLD_POINTER_SPACE);
2404a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return false;
2405303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2406a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_null_value(Oddball::cast(obj));
2407ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Oddball::cast(obj)->set_kind(Oddball::kNull);
240843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
24103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = Allocate(undefined_map(), OLD_POINTER_SPACE);
2411a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return false;
2412a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  }
2413a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  set_undefined_value(Oddball::cast(obj));
2414a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Oddball::cast(obj)->set_kind(Oddball::kUndefined);
2415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!InNewSpace(undefined_value()));
2416a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
2417a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  // Set preliminary exception sentinel value before actually initializing it.
2418a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  set_exception(null_value());
2419a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org
2420defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  // Allocate the empty descriptor array.
24213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
24223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateEmptyFixedArray();
2423a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return false;
2424303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2425defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  set_empty_descriptor_array(DescriptorArray::cast(obj));
242643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24279ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  // Allocate the constant pool array.
24283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
24293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateEmptyConstantPoolArray();
2430a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return false;
24319ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  }
24329ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  set_empty_constant_pool_array(ConstantPoolArray::cast(obj));
24339ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
24349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Fix the instance_descriptors for the existing maps.
243543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  meta_map()->set_code_cache(empty_fixed_array());
24362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  meta_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
243781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  meta_map()->init_back_pointer(undefined_value());
243889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  meta_map()->set_instance_descriptors(empty_descriptor_array());
243943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
244043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  fixed_array_map()->set_code_cache(empty_fixed_array());
24412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  fixed_array_map()->set_dependent_code(
24422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      DependentCode::cast(empty_fixed_array()));
244381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  fixed_array_map()->init_back_pointer(undefined_value());
244489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  fixed_array_map()->set_instance_descriptors(empty_descriptor_array());
244543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
244649ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  undefined_map()->set_code_cache(empty_fixed_array());
244749ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  undefined_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
244849ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  undefined_map()->init_back_pointer(undefined_value());
244949ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  undefined_map()->set_instance_descriptors(empty_descriptor_array());
245049ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org
245149ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  null_map()->set_code_cache(empty_fixed_array());
245249ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  null_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
245349ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  null_map()->init_back_pointer(undefined_value());
245449ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  null_map()->set_instance_descriptors(empty_descriptor_array());
245543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24569ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  constant_pool_array_map()->set_code_cache(empty_fixed_array());
24579ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  constant_pool_array_map()->set_dependent_code(
24589ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org      DependentCode::cast(empty_fixed_array()));
24599ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  constant_pool_array_map()->init_back_pointer(undefined_value());
24609ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  constant_pool_array_map()->set_instance_descriptors(empty_descriptor_array());
24619ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
246243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fix prototype object for existing maps.
246343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  meta_map()->set_prototype(null_value());
246443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  meta_map()->set_constructor(null_value());
246543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
246643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  fixed_array_map()->set_prototype(null_value());
246743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  fixed_array_map()->set_constructor(null_value());
2468defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
246949ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  undefined_map()->set_prototype(null_value());
247049ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  undefined_map()->set_constructor(null_value());
247149ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org
247249ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  null_map()->set_prototype(null_value());
247349ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  null_map()->set_constructor(null_value());
247443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24759ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  constant_pool_array_map()->set_prototype(null_value());
24769ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  constant_pool_array_map()->set_constructor(null_value());
24779ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
24781e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  {  // Map allocation
24793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ALLOCATE_MAP(instance_type, size, field_name)               \
24803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {                                                                 \
24813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Map* map;                                                       \
24823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (!AllocateMap((instance_type), size).To(&map)) return false; \
24833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    set_##field_name##_map(map);                                    \
24843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
248543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \
24873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name)
248843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24895c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, fixed_cow_array)
2490e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(fixed_array_map() != fixed_cow_array_map());
249143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24925c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info)
24935c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number)
24943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
24953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                 mutable_heap_number)
24965c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol)
24975c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign)
24986d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
249949ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole);
250049ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean);
250149ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized);
250249ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker);
250349ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, no_interceptor_result_sentinel);
2504a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception);
250549ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception);
250649ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org
2507fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    for (unsigned i = 0; i < arraysize(string_type_table); i++) {
25085c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      const StringTypeTable& entry = string_type_table[i];
25093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      {
25103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        AllocationResult allocation = AllocateMap(entry.type, entry.size);
2511a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        if (!allocation.To(&obj)) return false;
25125c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      }
2513a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      // Mark cons string maps as unstable, because their objects can change
2514a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      // maps during GC.
2515a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      Map* map = Map::cast(obj);
2516a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      if (StringShape(entry.type).IsCons()) map->mark_unstable();
2517a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      roots_[entry.index] = map;
2518303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
251943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25205c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(STRING_TYPE, undetectable_string)
25215c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    undetectable_string_map()->set_is_undetectable();
25225c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
25232c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(ONE_BYTE_STRING_TYPE, undetectable_one_byte_string);
25242c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    undetectable_one_byte_string_map()->set_is_undetectable();
25255c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
25265c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_DOUBLE_ARRAY_TYPE, fixed_double_array)
25275c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(BYTE_ARRAY_TYPE, byte_array)
25285c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FREE_SPACE_TYPE, free_space)
25295c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
25303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ALLOCATE_EXTERNAL_ARRAY_MAP(Type, type, TYPE, ctype, size)        \
25313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  ALLOCATE_MAP(EXTERNAL_##TYPE##_ARRAY_TYPE, ExternalArray::kAlignedSize, \
25323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org               external_##type##_array)
25335c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
25343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    TYPED_ARRAYS(ALLOCATE_EXTERNAL_ARRAY_MAP)
25355c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org#undef ALLOCATE_EXTERNAL_ARRAY_MAP
25365c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
25373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ALLOCATE_FIXED_TYPED_ARRAY_MAP(Type, type, TYPE, ctype, size) \
25383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  ALLOCATE_VARSIZE_MAP(FIXED_##TYPE##_ARRAY_TYPE, fixed_##type##_array)
2539af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
25403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    TYPED_ARRAYS(ALLOCATE_FIXED_TYPED_ARRAY_MAP)
2541af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef ALLOCATE_FIXED_TYPED_ARRAY_MAP
25425c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
2543486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements)
25445c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
25455c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
25465c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
25475c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell)
25485c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell)
25495c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler)
25505c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler)
25515c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
25525c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
2553fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    for (unsigned i = 0; i < arraysize(struct_table); i++) {
25545c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      const StructTable& entry = struct_table[i];
25555c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      Map* map;
25563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      if (!AllocateMap(entry.type, entry.size).To(&map)) return false;
25575c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      roots_[entry.index] = map;
25585c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    }
255937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
25605c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, hash_table)
25619e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, ordered_hash_table)
25626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
25635c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context)
25645c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context)
25655c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, with_context)
25665c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, block_context)
25675c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_context)
25685c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, global_context)
25694acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
25705c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, native_context)
25715c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    native_context_map()->set_dictionary_map(true);
25725c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    native_context_map()->set_visitor_id(
25735c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org        StaticVisitorBase::kVisitNativeContext);
2574f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
25755c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kAlignedSize,
25763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                 shared_function_info)
257746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
25783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kSize, message_object)
25793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, external)
25805c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    external_map()->set_is_extensible(false);
25815c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org#undef ALLOCATE_VARSIZE_MAP
25825c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org#undef ALLOCATE_MAP
258346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
258443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {  // Empty arrays
25863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    {
25873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      ByteArray* byte_array;
2588a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false;
25895c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      set_empty_byte_array(byte_array);
25905c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    }
259143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ALLOCATE_EMPTY_EXTERNAL_ARRAY(Type, type, TYPE, ctype, size)  \
25933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {                                                                   \
25943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ExternalArray* obj;                                               \
25953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (!AllocateEmptyExternalArray(kExternal##Type##Array).To(&obj)) \
25963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return false;                                                   \
25973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    set_empty_external_##type##_array(obj);                           \
25983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
259931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
2600af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(ALLOCATE_EMPTY_EXTERNAL_ARRAY)
26015c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org#undef ALLOCATE_EMPTY_EXTERNAL_ARRAY
2602895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
26033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
26043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {                                                                     \
26053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    FixedTypedArrayBase* obj;                                           \
26063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array).To(&obj)) \
26073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return false;                                                     \
26083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    set_empty_fixed_##type##_array(obj);                                \
26093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
2610895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
2611895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    TYPED_ARRAYS(ALLOCATE_EMPTY_FIXED_TYPED_ARRAY)
2612895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#undef ALLOCATE_EMPTY_FIXED_TYPED_ARRAY
2613eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  }
2614e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!InNewSpace(empty_fixed_array()));
261543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
261643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
261743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
261843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgAllocationResult Heap::AllocateHeapNumber(double value, MutableMode mode,
2620a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                          PretenureFlag pretenure) {
262143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Statically ensure that it is safe to allocate heap numbers in paged
262243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // spaces.
26233d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  int size = HeapNumber::kSize;
2624ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxRegularHeapObjectSize);
2625ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org
26263d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
2627c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
2628a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
26293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
26303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
2631a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
2632303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
263343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
263458a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  Map* map = mode == MUTABLE ? mutable_heap_number_map() : heap_number_map();
263558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  HeapObject::cast(result)->set_map_no_write_barrier(map);
263643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapNumber::cast(result)->set_value(value);
263743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
263843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
263943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
264043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2641a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateCell(Object* value) {
2642e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org  int size = Cell::kSize;
2643ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  STATIC_ASSERT(Cell::kSize <= Page::kMaxRegularHeapObjectSize);
2644e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org
2645a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
26463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
26473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, CELL_SPACE, CELL_SPACE);
2648a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
2649303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2650a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(cell_map());
265141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Cell::cast(result)->set_value(value);
265241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return result;
265341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
265441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
265541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
2656a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocatePropertyCell() {
2657e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org  int size = PropertyCell::kSize;
2658ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  STATIC_ASSERT(PropertyCell::kSize <= Page::kMaxRegularHeapObjectSize);
2659e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org
2660a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
2661a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation =
2662e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org      AllocateRaw(size, PROPERTY_CELL_SPACE, PROPERTY_CELL_SPACE);
2663a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&result)) return allocation;
2664e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
2665a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(global_property_cell_map());
26661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  PropertyCell* cell = PropertyCell::cast(result);
26671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  cell->set_dependent_code(DependentCode::cast(empty_fixed_array()),
26681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                           SKIP_WRITE_BARRIER);
266971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  cell->set_value(the_hole_value());
26706d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  cell->set_type(HeapType::None());
26712abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  return result;
26722abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
26732abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
26742abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
26753484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgvoid Heap::CreateApiObjects() {
26763484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  HandleScope scope(isolate());
26773484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Factory* factory = isolate()->factory();
26783484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Map> new_neander_map =
26793484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
268043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Don't use Smi-only elements optimizations for objects with the neander
2682c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // map. There are too many cases where element values are set directly with a
2683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // bottleneck to trap the Smi-only -> fast elements transition, and there
2684c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // appears to be no benefit for optimize this case.
2685830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  new_neander_map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND);
26863484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_neander_map(*new_neander_map);
268743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26883484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<JSObject> listeners = factory->NewNeanderObject();
26893484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<FixedArray> elements = factory->NewFixedArray(2);
26903484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  elements->set(0, Smi::FromInt(0));
26913484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  listeners->set_elements(*elements);
26923484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_message_listeners(*listeners);
269343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
269443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26952abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
26962abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgvoid Heap::CreateJSEntryStub() {
269742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  JSEntryStub stub(isolate(), StackFrame::ENTRY);
2698f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  set_js_entry_code(*stub.GetCode());
26992abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
27002abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
27012abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
27022abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgvoid Heap::CreateJSConstructEntryStub() {
270342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  JSEntryStub stub(isolate(), StackFrame::ENTRY_CONSTRUCT);
2704f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  set_js_construct_entry_code(*stub.GetCode());
27052abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
27062abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
27072abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
270843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::CreateFixedStubs() {
270943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Here we create roots for fixed stubs. They are needed at GC
271043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for cooking and uncooking (check out frames.cc).
271143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The eliminates the need for doing dictionary lookup in the
271243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // stub cache for these stubs.
2713c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  HandleScope scope(isolate());
2714f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
2715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Create stubs that should be there, so we don't unexpectedly have to
2716f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // create them if we need them during the creation of another stub.
2717f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Stub creation mixes raw pointers and handles in an unsafe manner so
2718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // we cannot create stubs while we are creating stubs.
2719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  CodeStub::GenerateStubsAheadOfTime(isolate());
2720f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
2721f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // MacroAssembler::Abort calls (usually enabled with --debug-code) depend on
2722f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // CEntryStub, so we need to call GenerateStubsAheadOfTime before JSEntryStub
2723f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // is created.
2724f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
27252abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // gcc-4.4 has problem generating correct code of following snippet:
27264d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // {  JSEntryStub stub;
27274d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  //    js_entry_code_ = *stub.GetCode();
27282abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // }
27294d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // {  JSConstructEntryStub stub;
27304d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  //    js_construct_entry_code_ = *stub.GetCode();
27312abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // }
27322abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // To workaround the problem, make separate functions without inlining.
27332abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  Heap::CreateJSEntryStub();
27342abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  Heap::CreateJSConstructEntryStub();
273543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
273643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
273743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
27383484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgvoid Heap::CreateInitialObjects() {
27399fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  HandleScope scope(isolate());
27409fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Factory* factory = isolate()->factory();
274143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
274258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  // The -0 value must be set before NewNumber works.
274358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  set_minus_zero_value(*factory->NewHeapNumber(-0.0, IMMUTABLE, TENURED));
2744e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(std::signbit(minus_zero_value()->Number()) != 0);
274543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
274658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  set_nan_value(
274758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      *factory->NewHeapNumber(base::OS::nan_value(), IMMUTABLE, TENURED));
274858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, IMMUTABLE, TENURED));
274943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2750fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  // The hole has not been created yet, but we want to put something
27514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // predictable in the gaps in the string table, so lets make that Smi zero.
2752fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  set_the_hole_value(reinterpret_cast<Oddball*>(Smi::FromInt(0)));
2753fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
27544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate initial string table.
27559fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  set_string_table(*StringTable::New(isolate(), kInitialStringTableSize));
275643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
27574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Finish initializing oddballs after creating the string table.
27583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Oddball::Initialize(isolate(), factory->undefined_value(), "undefined",
27593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                      factory->nan_value(), Oddball::kUndefined);
276043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2761a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // Initialize the null_value.
27623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Oddball::Initialize(isolate(), factory->null_value(), "null",
27633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                      handle(Smi::FromInt(0), isolate()), Oddball::kNull);
27643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
27653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_true_value(*factory->NewOddball(factory->boolean_map(), "true",
27669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                      handle(Smi::FromInt(1), isolate()),
27679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                      Oddball::kTrue));
27689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
27693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_false_value(*factory->NewOddball(factory->boolean_map(), "false",
27709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                       handle(Smi::FromInt(0), isolate()),
27719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                       Oddball::kFalse));
27729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
27733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_the_hole_value(*factory->NewOddball(factory->the_hole_map(), "hole",
27749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                          handle(Smi::FromInt(-1), isolate()),
27759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                          Oddball::kTheHole));
27769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
27773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_uninitialized_value(*factory->NewOddball(
27783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      factory->uninitialized_map(), "uninitialized",
27793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      handle(Smi::FromInt(-1), isolate()), Oddball::kUninitialized));
27803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
27813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_arguments_marker(*factory->NewOddball(
27823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      factory->arguments_marker_map(), "arguments_marker",
27833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      handle(Smi::FromInt(-4), isolate()), Oddball::kArgumentMarker));
27843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
27853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_no_interceptor_result_sentinel(*factory->NewOddball(
27863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      factory->no_interceptor_result_sentinel_map(),
27873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      "no_interceptor_result_sentinel", handle(Smi::FromInt(-2), isolate()),
27883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      Oddball::kOther));
27893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
27903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_termination_exception(*factory->NewOddball(
27913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      factory->termination_exception_map(), "termination_exception",
27923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      handle(Smi::FromInt(-3), isolate()), Oddball::kOther));
27933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
27943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_exception(*factory->NewOddball(factory->exception_map(), "exception",
27953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                     handle(Smi::FromInt(-5), isolate()),
27963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                     Oddball::kException));
2797a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org
2798fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  for (unsigned i = 0; i < arraysize(constant_string_table); i++) {
27999fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<String> str =
28009fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        factory->InternalizeUtf8String(constant_string_table[i].contents);
28019fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    roots_[constant_string_table[i].index] = *str;
280268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  }
280343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate the hidden string which is used to identify the hidden properties
28053b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  // in JSObjects. The hash code has a special value so that it will not match
28063b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  // the empty string when searching for the property. It cannot be part of the
280768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // loop above because it needs to be allocated manually with the special
28084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // hash code in place. The hash code for the hidden_string is zero to ensure
28093b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  // that it will always be at the first entry in property descriptors.
28103484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  hidden_string_ = *factory->NewOneByteInternalizedString(
28114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      OneByteVector("", 0), String::kEmptyStringHash);
28123b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org
2813865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  // Create the code_stubs dictionary. The initial size is set to avoid
28140b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // expanding the dictionary during bootstrapping.
2815865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  set_code_stubs(*UnseededNumberDictionary::New(isolate(), 128));
281643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2817865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  // Create the non_monomorphic_cache used in stub-cache.cc. The initial size
28180b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // is set to avoid expanding the dictionary during bootstrapping.
2819865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  set_non_monomorphic_cache(*UnseededNumberDictionary::New(isolate(), 64));
282043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28213484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_polymorphic_code_cache(PolymorphicCodeCache::cast(
28223484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      *factory->NewStruct(POLYMORPHIC_CODE_CACHE_TYPE)));
2823e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
2824720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  set_instanceof_cache_function(Smi::FromInt(0));
2825720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  set_instanceof_cache_map(Smi::FromInt(0));
2826720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  set_instanceof_cache_answer(Smi::FromInt(0));
2827720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
282843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CreateFixedStubs();
282943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2830d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  // Allocate the dictionary of intrinsic function names.
28313484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<NameDictionary> intrinsic_names =
28325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      NameDictionary::New(isolate(), Runtime::kNumFunctions, TENURED);
28333484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Runtime::InitializeIntrinsicFunctionNames(isolate(), intrinsic_names);
28343484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_intrinsic_function_names(*intrinsic_names);
2835d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
28363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_number_string_cache(
28373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      *factory->NewFixedArray(kInitialNumberStringCacheSize * 2, TENURED));
283843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
283959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // Allocate cache for single character one byte strings.
28403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_single_character_string_cache(
28413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      *factory->NewFixedArray(String::kMaxOneByteCharCode + 1, TENURED));
284243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28433484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  // Allocate cache for string split and regexp-multiple.
28443484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_string_split_cache(*factory->NewFixedArray(
28453484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
28463484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_regexp_multiple_cache(*factory->NewFixedArray(
28473484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
284878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
284943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate cache for external strings pointing to native source code.
28503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_natives_source_cache(
28513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      *factory->NewFixedArray(Natives::GetBuiltinsCount()));
285243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28533484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_undefined_cell(*factory->NewCell(factory->undefined_value()));
285426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
2855a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  // The symbol registry is initialized lazily.
2856a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  set_symbol_registry(undefined_value());
2857fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
2858e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Allocate object to hold object observation state.
28593484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_observation_state(*factory->NewJSObjectFromMap(
28603484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize)));
2861e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
286254ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  // Microtask queue uses the empty fixed array as a sentinel for "empty".
286354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  // Number of queued microtasks stored in Isolate::pending_microtask_count().
286454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  set_microtask_queue(empty_fixed_array());
2865ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
2866b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_detailed_stack_trace_symbol(*factory->NewPrivateOwnSymbol());
2867b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_elements_transition_symbol(*factory->NewPrivateOwnSymbol());
2868b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_frozen_symbol(*factory->NewPrivateOwnSymbol());
2869b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_megamorphic_symbol(*factory->NewPrivateOwnSymbol());
2870b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_premonomorphic_symbol(*factory->NewPrivateOwnSymbol());
2871b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_generic_symbol(*factory->NewPrivateOwnSymbol());
2872b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_nonexistent_symbol(*factory->NewPrivateOwnSymbol());
2873b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_normal_ic_symbol(*factory->NewPrivateOwnSymbol());
2874b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_observed_symbol(*factory->NewPrivateOwnSymbol());
2875b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_stack_trace_symbol(*factory->NewPrivateOwnSymbol());
2876b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  set_uninitialized_symbol(*factory->NewPrivateOwnSymbol());
2877a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  set_home_object_symbol(*factory->NewPrivateOwnSymbol());
2878a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
28793484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<SeededNumberDictionary> slow_element_dictionary =
28803484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      SeededNumberDictionary::New(isolate(), 0, TENURED);
28813484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  slow_element_dictionary->set_requires_slow_elements();
28823484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_empty_slow_element_dictionary(*slow_element_dictionary);
2883169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
28843484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  set_materialized_objects(*factory->NewFixedArray(0, TENURED));
288557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
2886d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // Handling of script id generation is in Factory::NewScript.
28876b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId));
28887be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
28893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  set_allocation_sites_scratchpad(
28903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      *factory->NewFixedArray(kAllocationSiteScratchpadSize, TENURED));
2891bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org  InitializeAllocationSitesScratchpad();
2892bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org
28935a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Initialize keyed lookup cache.
2894ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->keyed_lookup_cache()->Clear();
28955aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
28965aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Initialize context slot cache.
2897ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->context_slot_cache()->Clear();
28985aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
28995aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Initialize descriptor cache.
2900ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->descriptor_lookup_cache()->Clear();
29015a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
2902b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  // Initialize compilation cache.
2903ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->compilation_cache()->Clear();
290443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
290543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
290643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2907e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgbool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
2908e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  RootListIndex writable_roots[] = {
29093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kStoreBufferTopRootIndex,
29103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kStackLimitRootIndex,
29113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kNumberStringCacheRootIndex,
29123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kInstanceofCacheFunctionRootIndex,
29133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kInstanceofCacheMapRootIndex,
29143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kInstanceofCacheAnswerRootIndex,
29153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kCodeStubsRootIndex,
29163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kNonMonomorphicCacheRootIndex,
29173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kPolymorphicCodeCacheRootIndex,
29183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kLastScriptIdRootIndex,
29193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kEmptyScriptRootIndex,
29203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kRealStackLimitRootIndex,
29213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kArgumentsAdaptorDeoptPCOffsetRootIndex,
29223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kConstructStubDeoptPCOffsetRootIndex,
29233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kGetterStubDeoptPCOffsetRootIndex,
29243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kSetterStubDeoptPCOffsetRootIndex,
29253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      kStringTableRootIndex,
2926e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  };
2927e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
2928fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  for (unsigned int i = 0; i < arraysize(writable_roots); i++) {
29293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (root_index == writable_roots[i]) return true;
2930e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
2931e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return false;
2932e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
2933e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
2934e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
2935594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgbool Heap::RootCanBeTreatedAsConstant(RootListIndex root_index) {
2936594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return !RootCanBeWrittenAfterInitialization(root_index) &&
29373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         !InNewSpace(roots_array_start()[root_index]);
2938594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
2939594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
2940594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
29413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgObject* RegExpResultsCache::Lookup(Heap* heap, String* key_string,
29423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   Object* key_pattern, ResultsCacheType type) {
294378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  FixedArray* cache;
29444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!key_string->IsInternalizedString()) return Smi::FromInt(0);
294578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (type == STRING_SPLIT_SUBSTRINGS) {
2946e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(key_pattern->IsString());
29474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0);
294878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    cache = heap->string_split_cache();
294978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  } else {
2950e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(type == REGEXP_MULTIPLE_INDICES);
2951e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(key_pattern->IsFixedArray());
295278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    cache = heap->regexp_multiple_cache();
295378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
295478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
295578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  uint32_t hash = key_string->Hash();
295678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
29573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                    ~(kArrayEntriesPerCacheEntry - 1));
295878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (cache->get(index + kStringOffset) == key_string &&
295978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->get(index + kPatternOffset) == key_pattern) {
2960486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    return cache->get(index + kArrayOffset);
2961486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
296278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  index =
296378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
296478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (cache->get(index + kStringOffset) == key_string &&
296578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      cache->get(index + kPatternOffset) == key_pattern) {
2966486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    return cache->get(index + kArrayOffset);
2967486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
2968486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  return Smi::FromInt(0);
2969486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org}
2970486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
2971486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
29723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid RegExpResultsCache::Enter(Isolate* isolate, Handle<String> key_string,
29739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                               Handle<Object> key_pattern,
29749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                               Handle<FixedArray> value_array,
297578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                               ResultsCacheType type) {
29769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Factory* factory = isolate->factory();
29779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<FixedArray> cache;
29784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!key_string->IsInternalizedString()) return;
297978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (type == STRING_SPLIT_SUBSTRINGS) {
2980e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(key_pattern->IsString());
29814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (!key_pattern->IsInternalizedString()) return;
29829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    cache = factory->string_split_cache();
298378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  } else {
2984e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(type == REGEXP_MULTIPLE_INDICES);
2985e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(key_pattern->IsFixedArray());
29869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    cache = factory->regexp_multiple_cache();
298778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
298878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
298978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  uint32_t hash = key_string->Hash();
299078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
29913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                    ~(kArrayEntriesPerCacheEntry - 1));
2992486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (cache->get(index + kStringOffset) == Smi::FromInt(0)) {
29939fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    cache->set(index + kStringOffset, *key_string);
29949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    cache->set(index + kPatternOffset, *key_pattern);
29959fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    cache->set(index + kArrayOffset, *value_array);
299655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  } else {
299755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    uint32_t index2 =
299878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
299955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) {
30009fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      cache->set(index2 + kStringOffset, *key_string);
30019fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      cache->set(index2 + kPatternOffset, *key_pattern);
30029fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      cache->set(index2 + kArrayOffset, *value_array);
300355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    } else {
300455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      cache->set(index2 + kStringOffset, Smi::FromInt(0));
300555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      cache->set(index2 + kPatternOffset, Smi::FromInt(0));
300655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      cache->set(index2 + kArrayOffset, Smi::FromInt(0));
30079fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      cache->set(index + kStringOffset, *key_string);
30089fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      cache->set(index + kPatternOffset, *key_pattern);
30099fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      cache->set(index + kArrayOffset, *value_array);
301055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
3011486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
301278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // If the array is a reasonably short list of substrings, convert it into a
30134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // list of internalized strings.
301478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) {
301578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    for (int i = 0; i < value_array->length(); i++) {
30169fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Handle<String> str(String::cast(value_array->get(i)), isolate);
30179fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Handle<String> internalized_str = factory->InternalizeString(str);
30189fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      value_array->set(i, *internalized_str);
3019486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    }
3020486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
302178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // Convert backing store to a copy-on-write array.
30229fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map());
3023486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org}
3024486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
3025486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
302678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid RegExpResultsCache::Clear(FixedArray* cache) {
302778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  for (int i = 0; i < kRegExpResultsCacheSize; i++) {
3028486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    cache->set(i, Smi::FromInt(0));
3029486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
3030486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org}
3031486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
3032486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
3033fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgint Heap::FullSizeNumberStringCacheLength() {
3034fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Compute the size of the number string cache based on the max newspace size.
3035fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // The number string cache has a minimum size based on twice the initial cache
3036fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // size to ensure that it is bigger after being made 'full size'.
30373c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  int number_string_cache_size = max_semi_space_size_ / 512;
3038fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  number_string_cache_size = Max(kInitialNumberStringCacheSize * 2,
3039fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                                 Min(0x4000, number_string_cache_size));
3040fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // There is a string and a number per entry so the length is twice the number
3041fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // of entries.
3042fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  return number_string_cache_size * 2;
3043fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
3044fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
3045fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
30460c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgvoid Heap::FlushNumberStringCache() {
30470c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Flush the number to string cache.
30480c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  int len = number_string_cache()->length();
30490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  for (int i = 0; i < len; i++) {
30501f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.org    number_string_cache()->set_undefined(i);
30510c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
30520c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
30530c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
30540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3055bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.orgvoid Heap::FlushAllocationSitesScratchpad() {
3056bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org  for (int i = 0; i < allocation_sites_scratchpad_length_; i++) {
3057bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org    allocation_sites_scratchpad()->set_undefined(i);
3058bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org  }
3059bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org  allocation_sites_scratchpad_length_ = 0;
3060bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org}
3061bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org
3062bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org
3063bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.orgvoid Heap::InitializeAllocationSitesScratchpad() {
3064e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(allocation_sites_scratchpad()->length() ==
3065bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org         kAllocationSiteScratchpadSize);
3066bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org  for (int i = 0; i < kAllocationSiteScratchpadSize; i++) {
3067bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org    allocation_sites_scratchpad()->set_undefined(i);
3068bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org  }
3069bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org}
3070bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org
3071bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org
3072bc176057ae476990672de915df235c9aeadc8521titzer@chromium.orgvoid Heap::AddAllocationSiteToScratchpad(AllocationSite* site,
3073bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org                                         ScratchpadSlotMode mode) {
3074bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org  if (allocation_sites_scratchpad_length_ < kAllocationSiteScratchpadSize) {
3075f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // We cannot use the normal write-barrier because slots need to be
3076f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // recorded with non-incremental marking as well. We have to explicitly
3077f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // record the slot to take evacuation candidates into account.
30783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    allocation_sites_scratchpad()->set(allocation_sites_scratchpad_length_,
30793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                       site, SKIP_WRITE_BARRIER);
3080f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Object** slot = allocation_sites_scratchpad()->RawFieldOfElementAt(
3081f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        allocation_sites_scratchpad_length_);
3082bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org
3083bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    if (mode == RECORD_SCRATCHPAD_SLOT) {
3084bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      // We need to allow slots buffer overflow here since the evacuation
3085bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      // candidates are not part of the global list of old space pages and
3086bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      // releasing an evacuation candidate due to a slots buffer overflow
3087bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      // results in lost pages.
30883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      mark_compact_collector()->RecordSlot(slot, slot, *slot,
30893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                           SlotsBuffer::IGNORE_OVERFLOW);
3090bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    }
3091bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org    allocation_sites_scratchpad_length_++;
3092bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org  }
3093bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org}
3094bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org
3095bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org
30963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgMap* Heap::MapForExternalArrayType(ExternalArrayType array_type) {
30973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  return Map::cast(roots_[RootIndexForExternalArrayType(array_type)]);
30983811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
30993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
31003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
31013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgHeap::RootListIndex Heap::RootIndexForExternalArrayType(
31023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    ExternalArrayType array_type) {
31033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  switch (array_type) {
31043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ARRAY_TYPE_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \
31053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  case kExternal##Type##Array:                                  \
31063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    return kExternal##Type##ArrayMapRootIndex;
3107af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
3108af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(ARRAY_TYPE_TO_ROOT_INDEX)
3109af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef ARRAY_TYPE_TO_ROOT_INDEX
3110af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
31113811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    default:
31123811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      UNREACHABLE();
31133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      return kUndefinedValueRootIndex;
31143811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
31153811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
31163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
3117ea9b8ba58955b7efcc3e1550dd33a44fb4530136hpayer@chromium.org
31185c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.orgMap* Heap::MapForFixedTypedArray(ExternalArrayType array_type) {
31195c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  return Map::cast(roots_[RootIndexForFixedTypedArray(array_type)]);
31205c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org}
31215c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
31225c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
31235c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.orgHeap::RootListIndex Heap::RootIndexForFixedTypedArray(
31245c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    ExternalArrayType array_type) {
31255c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  switch (array_type) {
31263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ARRAY_TYPE_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \
31273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  case kExternal##Type##Array:                                  \
31283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    return kFixed##Type##ArrayMapRootIndex;
3129af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
3130af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(ARRAY_TYPE_TO_ROOT_INDEX)
3131af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef ARRAY_TYPE_TO_ROOT_INDEX
3132af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
31335c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    default:
31345c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      UNREACHABLE();
31355c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      return kUndefinedValueRootIndex;
31365c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  }
31375c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org}
31385c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
31395c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
31404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgHeap::RootListIndex Heap::RootIndexForEmptyExternalArray(
31414e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    ElementsKind elementsKind) {
31424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  switch (elementsKind) {
31433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ELEMENT_KIND_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \
31443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  case EXTERNAL_##TYPE##_ELEMENTS:                                \
31453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    return kEmptyExternal##Type##ArrayRootIndex;
3146af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
3147af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(ELEMENT_KIND_TO_ROOT_INDEX)
3148af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef ELEMENT_KIND_TO_ROOT_INDEX
3149af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
31504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    default:
31514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      UNREACHABLE();
31524e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      return kUndefinedValueRootIndex;
31534e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
31544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
31554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
3156e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3157895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgHeap::RootListIndex Heap::RootIndexForEmptyFixedTypedArray(
3158895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    ElementsKind elementsKind) {
3159895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  switch (elementsKind) {
31603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ELEMENT_KIND_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \
31613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  case TYPE##_ELEMENTS:                                           \
31623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    return kEmptyFixed##Type##ArrayRootIndex;
3163895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
3164895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    TYPED_ARRAYS(ELEMENT_KIND_TO_ROOT_INDEX)
3165895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#undef ELEMENT_KIND_TO_ROOT_INDEX
3166895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    default:
3167895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      UNREACHABLE();
3168895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      return kUndefinedValueRootIndex;
3169895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
3170895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
3171895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
3172895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
31734e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgExternalArray* Heap::EmptyExternalArrayForMap(Map* map) {
31744e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  return ExternalArray::cast(
31754e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      roots_[RootIndexForEmptyExternalArray(map->elements_kind())]);
31764e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
31774e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
31784e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
3179895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgFixedTypedArrayBase* Heap::EmptyFixedTypedArrayForMap(Map* map) {
3180895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return FixedTypedArrayBase::cast(
3181895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]);
3182895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
3183895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
3184895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
3185a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateForeign(Address address,
3186a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                       PretenureFlag pretenure) {
3187ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Statically ensure that it is safe to allocate foreigns in paged spaces.
3188ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize);
31890b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
3190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Foreign* result;
3191a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation = Allocate(foreign_map(), space);
3192a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&result)) return allocation;
3193c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  result->set_foreign_address(address);
319443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
319543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
319643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
319743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3198a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateByteArray(int length, PretenureFlag pretenure) {
31990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  if (length < 0 || length > ByteArray::kMaxLength) {
3200a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
32010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
3202a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int size = ByteArray::SizeFor(length);
32033d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
3204a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
32053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
32063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
3207a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
3208303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
320943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3210a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(byte_array_map());
3211a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ByteArray::cast(result)->set_length(length);
321243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
321343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
321443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
321543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32166f10e41fef1524c70846d970268de222e41c594cager@chromium.orgvoid Heap::CreateFillerObjectAt(Address addr, int size) {
32176f10e41fef1524c70846d970268de222e41c594cager@chromium.org  if (size == 0) return;
32186f10e41fef1524c70846d970268de222e41c594cager@chromium.org  HeapObject* filler = HeapObject::FromAddress(addr);
32196f10e41fef1524c70846d970268de222e41c594cager@chromium.org  if (size == kPointerSize) {
322064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    filler->set_map_no_write_barrier(one_pointer_filler_map());
3221013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  } else if (size == 2 * kPointerSize) {
322264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    filler->set_map_no_write_barrier(two_pointer_filler_map());
32236f10e41fef1524c70846d970268de222e41c594cager@chromium.org  } else {
322464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    filler->set_map_no_write_barrier(free_space_map());
3225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FreeSpace::cast(filler)->set_size(size);
32266f10e41fef1524c70846d970268de222e41c594cager@chromium.org  }
32276f10e41fef1524c70846d970268de222e41c594cager@chromium.org}
32286f10e41fef1524c70846d970268de222e41c594cager@chromium.org
32296f10e41fef1524c70846d970268de222e41c594cager@chromium.org
3230b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.orgbool Heap::CanMoveObjectStart(HeapObject* object) {
3231b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  Address address = object->address();
3232b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  bool is_in_old_pointer_space = InOldPointerSpace(address);
3233b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  bool is_in_old_data_space = InOldDataSpace(address);
3234b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
3235b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  if (lo_space()->Contains(object)) return false;
3236b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
3237f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Page* page = Page::FromAddress(address);
3238f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // We can move the object start if:
3239f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // (1) the object is not in old pointer or old data space,
3240f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // (2) the page of the object was already swept,
3241f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // (3) the page was already concurrently swept. This case is an optimization
3242f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // for concurrent sweeping. The WasSwept predicate for concurrently swept
3243f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // pages is set after sweeping all pages.
3244b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  return (!is_in_old_pointer_space && !is_in_old_data_space) ||
32452b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org         page->WasSwept() || page->SweepingCompleted();
3246b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org}
3247b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
3248b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
32495697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.orgvoid Heap::AdjustLiveBytes(Address address, int by, InvocationMode mode) {
32505697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  if (incremental_marking()->IsMarking() &&
32515697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org      Marking::IsBlack(Marking::MarkBitFrom(address))) {
32525697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org    if (mode == FROM_GC) {
32535697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org      MemoryChunk::IncrementLiveBytesFromGC(address, by);
32545697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org    } else {
32555697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org      MemoryChunk::IncrementLiveBytesFromMutator(address, by);
32565697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org    }
32575697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  }
32585697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org}
32595697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org
32605697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org
32613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgFixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object,
32623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                         int elements_to_trim) {
32633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize;
32643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  const int bytes_to_trim = elements_to_trim * element_size;
32653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Map* map = object->map();
32663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
32673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // For now this trick is only applied to objects in new and paged space.
32683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // In large object space the object's start must coincide with chunk
32693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // and thus the trick is just not applicable.
32703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(!lo_space()->Contains(object));
32713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(object->map() != fixed_cow_array_map());
32723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
32733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  STATIC_ASSERT(FixedArrayBase::kMapOffset == 0);
32743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize);
32753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize);
32763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
32773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  const int len = object->length();
32783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(elements_to_trim <= len);
32793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
32803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Calculate location of new array start.
32813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Address new_start = object->address() + bytes_to_trim;
32823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
32833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Technically in new space this write might be omitted (except for
32843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // debug mode which iterates through the heap), but to play safer
32853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // we still do it.
32863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  CreateFillerObjectAt(object->address(), bytes_to_trim);
32873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
32883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Initialize header of the trimmed array. Since left trimming is only
32893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // performed on pages which are not concurrently swept creating a filler
32903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // object does not require synchronization.
32913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(CanMoveObjectStart(object));
32923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Object** former_start = HeapObject::RawField(object, 0);
32933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int new_start_index = elements_to_trim * (element_size / kPointerSize);
32943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  former_start[new_start_index] = map;
32953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim);
32963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  FixedArrayBase* new_object =
32973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      FixedArrayBase::cast(HeapObject::FromAddress(new_start));
32983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
32993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Maintain consistency of live bytes during incremental marking
33003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  marking()->TransferMark(object->address(), new_start);
33013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  AdjustLiveBytes(new_start, -bytes_to_trim, Heap::FROM_MUTATOR);
33023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Notify the heap profiler of change in object layout.
33043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  OnMoveEvent(new_object, object, new_object->Size());
33053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  return new_object;
33063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
33073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// Force instantiation of templatized method.
33103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate
33113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid Heap::RightTrimFixedArray<Heap::FROM_GC>(FixedArrayBase*, int);
33123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate
33133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid Heap::RightTrimFixedArray<Heap::FROM_MUTATOR>(FixedArrayBase*, int);
33143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate<Heap::InvocationMode mode>
33173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) {
33183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize;
33193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  const int bytes_to_trim = elements_to_trim * element_size;
33203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // For now this trick is only applied to objects in new and paged space.
33223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(object->map() != fixed_cow_array_map());
33233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  const int len = object->length();
33253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(elements_to_trim < len);
33263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Calculate location of new array end.
33283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Address new_end = object->address() + object->Size() - bytes_to_trim;
33293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Technically in new space this write might be omitted (except for
33313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // debug mode which iterates through the heap), but to play safer
33323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // we still do it.
33335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // We do not create a filler for objects in large object space.
33345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // TODO(hpayer): We should shrink the large object page if the size
33355e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // of the object changed significantly.
33365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  if (!lo_space()->Contains(object)) {
33375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    CreateFillerObjectAt(new_end, bytes_to_trim);
33385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  }
33393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Initialize header of the trimmed array. We are storing the new length
33413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // using release store after creating a filler for the left-over space to
33423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // avoid races with the sweeper thread.
33433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  object->synchronized_set_length(len - elements_to_trim);
33443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Maintain consistency of live bytes during incremental marking
33463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  AdjustLiveBytes(object->address(), -bytes_to_trim, mode);
33473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Notify the heap profiler of change in object layout. The array may not be
33493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // moved during GC, and size has to be adjusted nevertheless.
33503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  HeapProfiler* profiler = isolate()->heap_profiler();
33513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (profiler->is_tracking_allocations()) {
33523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    profiler->UpdateObjectSizeEvent(object->address(), object->Size());
33533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
33543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
33553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
33563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
3357a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateExternalArray(int length,
33583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                             ExternalArrayType array_type,
33593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                             void* external_pointer,
33603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                             PretenureFlag pretenure) {
33613d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  int size = ExternalArray::kAlignedSize;
33623d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
3363a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
33643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
33653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
3366a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
3367303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
33683811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
33693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  result->set_map_no_write_barrier(MapForExternalArrayType(array_type));
3370a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ExternalArray::cast(result)->set_length(length);
3371a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ExternalArray::cast(result)->set_external_pointer(external_pointer);
33723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  return result;
33733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
33743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
33753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic void ForFixedTypedArray(ExternalArrayType array_type, int* element_size,
33765c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org                               ElementsKind* element_kind) {
33775c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  switch (array_type) {
33783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
33793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  case kExternal##Type##Array:                          \
33803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    *element_size = size;                               \
33813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    *element_kind = TYPE##_ELEMENTS;                    \
33823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    return;
3383af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
3384af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
3385af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
3386af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
33875c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    default:
33883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      *element_size = 0;               // Bogus
33895c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      *element_kind = UINT8_ELEMENTS;  // Bogus
33905c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      UNREACHABLE();
33915c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  }
33925c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org}
33935c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
33945c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
3395a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateFixedTypedArray(int length,
3396a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                               ExternalArrayType array_type,
3397a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                               PretenureFlag pretenure) {
33985c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  int element_size;
33995c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  ElementsKind elements_kind;
34005c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  ForFixedTypedArray(array_type, &element_size, &elements_kind);
34013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int size = OBJECT_POINTER_ALIGN(length * element_size +
34023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                  FixedTypedArrayBase::kDataOffset);
34035c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org#ifndef V8_HOST_ARCH_64_BIT
3404af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  if (array_type == kExternalFloat64Array) {
34055c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    size += kPointerSize;
34065c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  }
34075c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org#endif
34085c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
34095c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
34105c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  HeapObject* object;
3411a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
3412a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&object)) return allocation;
34135c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
3414af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  if (array_type == kExternalFloat64Array) {
34155c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    object = EnsureDoubleAligned(this, object, size);
34165c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  }
34175c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
3418a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  object->set_map(MapForFixedTypedArray(array_type));
3419a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object);
34205c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  elements->set_length(length);
3421895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  memset(elements->DataPtr(), 0, elements->DataSize());
34225c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  return elements;
34235c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org}
34245c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
34253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
34264b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.orgAllocationResult Heap::AllocateCode(int object_size, bool immovable) {
3427e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment));
34284b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  AllocationResult allocation =
34294b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      AllocateRaw(object_size, CODE_SPACE, CODE_SPACE);
34304b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
343156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  HeapObject* result;
3432a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&result)) return allocation;
343343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34344b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  if (immovable) {
34354b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    Address address = result->address();
34364b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    // Code objects which should stay at a fixed address are allocated either
34374b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    // in the first page of code space (objects on the first page of each space
34384b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    // are never moved) or in large object space.
34394b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    if (!code_space_->FirstPage()->Contains(address) &&
34404b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org        MemoryChunk::FromAddress(address)->owner()->identity() != LO_SPACE) {
34414b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      // Discard the first code allocation, which was on a page where it could
34424b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      // be moved.
34434b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      CreateFillerObjectAt(result->address(), object_size);
34444b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE);
34454b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      if (!allocation.To(&result)) return allocation;
34464b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      OnAllocationEvent(result, object_size);
34474b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    }
344856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  }
344943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
345056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  result->set_map_no_write_barrier(code_map());
345143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Code* code = Code::cast(result);
34523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(isolate_->code_range() == NULL || !isolate_->code_range()->valid() ||
34531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org         isolate_->code_range()->contains(code->address()));
3454659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  code->set_gc_metadata(Smi::FromInt(0));
345588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  code->set_ic_age(global_ic_age_);
345643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return code;
345743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
345843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
345943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3460a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::CopyCode(Code* code) {
3461a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation;
3462a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* new_constant_pool;
3463763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (FLAG_enable_ool_constant_pool &&
3464763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      code->constant_pool() != empty_constant_pool_array()) {
3465763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // Copy the constant pool, since edits to the copied code may modify
3466763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // the constant pool.
3467a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    allocation = CopyConstantPoolArray(code->constant_pool());
3468a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&new_constant_pool)) return allocation;
3469763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
3470763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    new_constant_pool = empty_constant_pool_array();
3471763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
3472763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
34734b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  HeapObject* result;
347443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate an object the same size as the code object.
347543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int obj_size = code->Size();
34764b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  allocation = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE);
3477a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&result)) return allocation;
347843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
347943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Copy code object.
348043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address old_addr = code->address();
3481a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  Address new_addr = result->address();
348230ce411529579186181838984710b0b0980857aaricow@chromium.org  CopyBlock(new_addr, old_addr, obj_size);
348343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Code* new_code = Code::cast(result);
3484763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3485763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Update the constant pool.
3486763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  new_code->set_constant_pool(new_constant_pool);
3487763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3488763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Relocate the copy.
34893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(isolate_->code_range() == NULL || !isolate_->code_range()->valid() ||
34901845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org         isolate_->code_range()->contains(code->address()));
349143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  new_code->Relocate(new_addr - old_addr);
349243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return new_code;
349343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
349443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
349543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3496a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::CopyCode(Code* code, Vector<byte> reloc_info) {
3497763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Allocate ByteArray and ConstantPoolArray before the Code object, so that we
3498763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // do not risk leaving uninitialized Code object (and breaking the heap).
3499a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ByteArray* reloc_info_array;
35003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
35013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation =
3502303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateByteArray(reloc_info.length(), TENURED);
3503a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&reloc_info_array)) return allocation;
3504303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3505a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* new_constant_pool;
3506763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (FLAG_enable_ool_constant_pool &&
3507763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      code->constant_pool() != empty_constant_pool_array()) {
3508763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // Copy the constant pool, since edits to the copied code may modify
3509763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // the constant pool.
35103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = CopyConstantPoolArray(code->constant_pool());
3511a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&new_constant_pool)) return allocation;
3512763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
3513763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    new_constant_pool = empty_constant_pool_array();
3514763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
35154a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
35164a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment);
3517086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
35186a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  int new_obj_size = Code::SizeFor(new_body_size);
3519086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3520086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  Address old_addr = code->address();
3521086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3522b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  size_t relocation_offset =
35234a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com      static_cast<size_t>(code->instruction_end() - old_addr);
3524086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3525a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
35264b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  AllocationResult allocation =
35274b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE);
3528a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&result)) return allocation;
3529086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3530086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Copy code object.
3531a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  Address new_addr = result->address();
3532086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3533086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Copy header and instructions.
3534f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CopyBytes(new_addr, old_addr, relocation_offset);
3535086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3536086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  Code* new_code = Code::cast(result);
3537a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  new_code->set_relocation_info(reloc_info_array);
3538086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3539763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Update constant pool.
3540763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  new_code->set_constant_pool(new_constant_pool);
3541763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
35424a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  // Copy patched rinfo.
35433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  CopyBytes(new_code->relocation_start(), reloc_info.start(),
3544f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org            static_cast<size_t>(reloc_info.length()));
3545086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3546086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Relocate the copy.
35473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(isolate_->code_range() == NULL || !isolate_->code_range()->valid() ||
35481845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org         isolate_->code_range()->contains(code->address()));
3549086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  new_code->Relocate(new_addr - old_addr);
3550086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3551c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
3552a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (FLAG_verify_heap) code->ObjectVerify();
3553086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org#endif
3554086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  return new_code;
3555086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org}
3556086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3557086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
3558c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.orgvoid Heap::InitializeAllocationMemento(AllocationMemento* memento,
3559c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org                                       AllocationSite* allocation_site) {
3560c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org  memento->set_map_no_write_barrier(allocation_memento_map());
3561e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(allocation_site->map() == allocation_site_map());
3562c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org  memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER);
3563c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org  if (FLAG_allocation_site_pretenuring) {
3564c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    allocation_site->IncrementMementoCreateCount();
3565c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org  }
3566c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org}
3567c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
3568c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
3569a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::Allocate(Map* map, AllocationSpace space,
35703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                AllocationSite* allocation_site) {
3571e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(gc_state_ == NOT_IN_GC);
3572e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map->instance_type() != MAP_TYPE);
35730c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // If allocation failures are disallowed, we may allocate in a different
35740c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // space when new space is full and the object is not a large object.
35750c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  AllocationSpace retry_space =
35760c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type());
35774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int size = map->instance_size();
3578bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  if (allocation_site != NULL) {
3579bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    size += AllocationMemento::kSize;
3580bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  }
3581a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
3582a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation = AllocateRaw(size, space, retry_space);
3583a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&result)) return allocation;
358427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  // No need for write barrier since object is white and map is in old space.
3585a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(map);
3586bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  if (allocation_site != NULL) {
3587bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
3588bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org        reinterpret_cast<Address>(result) + map->instance_size());
3589bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    InitializeAllocationMemento(alloc_memento, allocation_site);
3590bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  }
359143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
359243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
359343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
359443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid Heap::InitializeJSObjectFromMap(JSObject* obj, FixedArray* properties,
359643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                     Map* map) {
359743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  obj->set_properties(properties);
359843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  obj->initialize_elements();
359943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // TODO(1240798): Initialize the object's body using valid initial values
360043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // according to the object's initial map.  For example, if the map's
360143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // instance type is JS_ARRAY_TYPE, the length field should be initialized
36022efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // to a number (e.g. Smi::FromInt(0)) and the elements initialized to a
36032efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // fixed array (e.g. Heap::empty_fixed_array()).  Currently, the object
360443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // verification code has to cope with (temporarily) invalid objects.  See
360543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for example, JSArray::JSArrayVerify).
36064a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  Object* filler;
36074a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // We cannot always fill with one_pointer_filler_map because objects
36084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // created from API functions expect their internal fields to be initialized
36094a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // with undefined_value.
3610c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Pre-allocated fields need to be initialized with undefined_value as well
3611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // so that object accesses before the constructor completes (e.g. in the
3612c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // debugger) will not cause a crash.
36134a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  if (map->constructor()->IsJSFunction() &&
36143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      JSFunction::cast(map->constructor())
36153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          ->IsInobjectSlackTrackingInProgress()) {
36164a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    // We might want to shrink the object later.
3617e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(obj->GetInternalFieldCount() == 0);
36184a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    filler = Heap::one_pointer_filler_map();
36194a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  } else {
36204a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    filler = Heap::undefined_value();
36214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  }
3622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  obj->InitializeBody(map, Heap::undefined_value(), filler);
362343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
362443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
362543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3626a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateJSObjectFromMap(
36273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Map* map, PretenureFlag pretenure, bool allocate_properties,
3628bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    AllocationSite* allocation_site) {
362943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // JSFunctions should be allocated using AllocateFunction to be
363043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // properly initialized.
3631e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map->instance_type() != JS_FUNCTION_TYPE);
363243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
363340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  // Both types of global objects should be allocated using
363440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  // AllocateGlobalObject to be properly initialized.
3635e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map->instance_type() != JS_GLOBAL_OBJECT_TYPE);
3636e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map->instance_type() != JS_BUILTINS_OBJECT_TYPE);
36370b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
363843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate the backing storage for the properties.
3639594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  FixedArray* properties;
3640594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (allocate_properties) {
3641594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int prop_size = map->InitialPropertiesLength();
3642e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(prop_size >= 0);
36433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    {
36443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      AllocationResult allocation = AllocateFixedArray(prop_size, pretenure);
3645a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if (!allocation.To(&properties)) return allocation;
3646594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
3647594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else {
3648594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    properties = empty_fixed_array();
3649303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
365043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
365143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate the JSObject.
36523d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  int size = map->instance_size();
36533d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure);
3654a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  JSObject* js_obj;
3655a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation = Allocate(map, space, allocation_site);
3656a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&js_obj)) return allocation;
36574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
36584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Initialize the JSObject.
3659a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  InitializeJSObjectFromMap(js_obj, properties, map);
36603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(js_obj->HasFastElements() || js_obj->HasExternalArrayElements() ||
3661a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org         js_obj->HasFixedTypedArrayElements());
3662a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  return js_obj;
36634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
36644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
36654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
3666a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateJSObject(JSFunction* constructor,
3667a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                        PretenureFlag pretenure,
3668a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                        AllocationSite* allocation_site) {
3669e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(constructor->has_initial_map());
36702abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
3671bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  // Allocate the object based on the constructors initial map.
3672a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation = AllocateJSObjectFromMap(
3673a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      constructor->initial_map(), pretenure, true, allocation_site);
36744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org#ifdef DEBUG
36754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Make sure result is NOT a global object if valid.
3676a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* obj;
3677e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!allocation.To(&obj) || !obj->IsGlobalObject());
36784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org#endif
3679a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  return allocation;
36804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
36814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
36824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
3683a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
36845a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Never used to copy functions.  If functions need to be copied we
36855a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // have to be careful to clear the literals array.
3686e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  SLOW_DCHECK(!source->IsJSFunction());
36875a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
36885a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Make the clone.
36895a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  Map* map = source->map();
36905a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  int object_size = map->instance_size();
3691a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* clone;
36929bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
3693e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type()));
3694528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
36954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
36964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
36974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // If we're forced to always allocate, we use the general allocation
36984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // functions which may leave us with an object in old space.
36994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (always_allocate()) {
37003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    {
37013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      AllocationResult allocation =
37024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE);
3703a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if (!allocation.To(&clone)) return allocation;
37044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
3705a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Address clone_address = clone->address();
37063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    CopyBlock(clone_address, source->address(), object_size);
37074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // Update write barrier for all fields that lie beyond the header.
37083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    RecordWrites(clone_address, JSObject::kHeaderSize,
37094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                 (object_size - JSObject::kHeaderSize) / kPointerSize);
37104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else {
37114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    wb_mode = SKIP_WRITE_BARRIER;
37124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
37133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    {
37143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      int adjusted_object_size =
37153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          site != NULL ? object_size + AllocationMemento::kSize : object_size;
37163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      AllocationResult allocation =
3717935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org          AllocateRaw(adjusted_object_size, NEW_SPACE, NEW_SPACE);
3718a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if (!allocation.To(&clone)) return allocation;
37194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
3720e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    SLOW_DCHECK(InNewSpace(clone));
37214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // Since we know the clone is allocated in new space, we can copy
37224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // the contents without worrying about updating the write barrier.
37233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    CopyBlock(clone->address(), source->address(), object_size);
37244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
3725528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (site != NULL) {
3726528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
3727528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          reinterpret_cast<Address>(clone) + object_size);
3728c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org      InitializeAllocationMemento(alloc_memento, site);
3729303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
373046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  }
373146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
37323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  SLOW_DCHECK(JSObject::cast(clone)->GetElementsKind() ==
37333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              source->GetElementsKind());
37342c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
37355a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  FixedArray* properties = FixedArray::cast(source->properties());
37365a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Update elements if necessary.
3737b26c50a70863498de657ad44be2cffa49ccdcbeaager@chromium.org  if (elements->length() > 0) {
3738a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    FixedArrayBase* elem;
37393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    {
37403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      AllocationResult allocation;
37412c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      if (elements->map() == fixed_cow_array_map()) {
3742a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        allocation = FixedArray::cast(elements);
37432c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      } else if (source->HasFastDoubleElements()) {
3744a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        allocation = CopyFixedDoubleArray(FixedDoubleArray::cast(elements));
37452c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      } else {
3746a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        allocation = CopyFixedArray(FixedArray::cast(elements));
37472c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      }
3748a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if (!allocation.To(&elem)) return allocation;
3749303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
3750a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    JSObject::cast(clone)->set_elements(elem, wb_mode);
37515a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
37525a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Update properties if necessary.
37535a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  if (properties->length() > 0) {
3754a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    FixedArray* prop;
37553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    {
37563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      AllocationResult allocation = CopyFixedArray(properties);
3757a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if (!allocation.To(&prop)) return allocation;
3758303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
3759a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    JSObject::cast(clone)->set_properties(prop, wb_mode);
37605a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
37615a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Return the new clone.
37625a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return clone;
37635a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
37645a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
37655a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
37663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic inline void WriteOneByteData(Vector<const char> vector, uint8_t* chars,
376746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                                    int len) {
37682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // Only works for one byte strings.
3769e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(vector.length() == len);
3770d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemCopy(chars, vector.start(), len);
377146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
377246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
37733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic inline void WriteTwoByteData(Vector<const char> vector, uint16_t* chars,
377446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                                    int len) {
377546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  const uint8_t* stream = reinterpret_cast<const uint8_t*>(vector.start());
377646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  unsigned stream_length = vector.length();
377746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  while (stream_length != 0) {
377846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    unsigned consumed = 0;
377946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    uint32_t c = unibrow::Utf8::ValueOf(stream, stream_length, &consumed);
3780e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(c != unibrow::Utf8::kBadChar);
3781e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(consumed <= stream_length);
378246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    stream_length -= consumed;
378346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    stream += consumed;
378446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
378546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      len -= 2;
378646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      if (len < 0) break;
378746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      *chars++ = unibrow::Utf16::LeadSurrogate(c);
378846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      *chars++ = unibrow::Utf16::TrailSurrogate(c);
378946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    } else {
379046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      len -= 1;
379146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      if (len < 0) break;
379246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      *chars++ = c;
37930c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
379443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3795e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(stream_length == 0);
3796e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(len == 0);
379746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
379843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3799a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
380046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgstatic inline void WriteOneByteData(String* s, uint8_t* chars, int len) {
3801e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(s->length() == len);
380246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  String::WriteToFlat(s, chars, 0, len);
380346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
3804a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
3805e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
380646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgstatic inline void WriteTwoByteData(String* s, uint16_t* chars, int len) {
3807e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(s->length() == len);
380846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  String::WriteToFlat(s, chars, 0, len);
380946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
3810a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
3811a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
38123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <bool is_one_byte, typename T>
38133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgAllocationResult Heap::AllocateInternalizedStringImpl(T t, int chars,
38143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                      uint32_t hash_field) {
3815e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(chars >= 0);
381643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute map and object size.
381743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int size;
381843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Map* map;
381943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3820e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LE(0, chars);
3821e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_GE(String::kMaxLength, chars);
3822a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (is_one_byte) {
38232c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    map = one_byte_internalized_string_map();
3824fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    size = SeqOneByteString::SizeFor(chars);
382543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
38264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    map = internalized_string_map();
38277c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    size = SeqTwoByteString::SizeFor(chars);
382843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
38293d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
383043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
383143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate string.
3832a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
38333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
38343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
3835a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
3836303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
383743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3838a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(map);
3839ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Set length and hash fields of the allocated string.
3840870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  String* answer = String::cast(result);
3841ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  answer->set_length(chars);
3842ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  answer->set_hash_field(hash_field);
384343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3844e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(size, answer->Size());
384543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3846a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (is_one_byte) {
384746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars);
3848a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
384946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars);
385043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3851870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  return answer;
385243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
385343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
385443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3855a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Need explicit instantiations.
38563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate AllocationResult Heap::AllocateInternalizedStringImpl<true>(String*,
38573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                                     int,
38583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                                     uint32_t);
38593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate AllocationResult Heap::AllocateInternalizedStringImpl<false>(String*,
38603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                                      int,
38613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                                      uint32_t);
38623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate AllocationResult Heap::AllocateInternalizedStringImpl<false>(
38634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Vector<const char>, int, uint32_t);
3864a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
3865a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
3866a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateRawOneByteString(int length,
3867a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                                PretenureFlag pretenure) {
3868e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LE(0, length);
3869e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_GE(String::kMaxLength, length);
3870fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  int size = SeqOneByteString::SizeFor(length);
3871e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(size <= SeqOneByteString::kMaxSize);
38723d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
3873c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
3874a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
38753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
38763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
3877a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
3878303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
387943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
388043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Partially initialize the object.
38812c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  result->set_map_no_write_barrier(one_byte_string_map());
388243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  String::cast(result)->set_length(length);
3883ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  String::cast(result)->set_hash_field(String::kEmptyHashField);
3884e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(size, HeapObject::cast(result)->Size());
388515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org
388643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
388743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
388843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
388943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3890a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateRawTwoByteString(int length,
3891a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                                PretenureFlag pretenure) {
3892e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LE(0, length);
3893e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_GE(String::kMaxLength, length);
38947c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  int size = SeqTwoByteString::SizeFor(length);
3895e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(size <= SeqTwoByteString::kMaxSize);
38963d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
3897c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
3898a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
38993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
39003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
3901a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
3902303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
390343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
390443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Partially initialize the object.
3905a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(string_map());
390643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  String::cast(result)->set_length(length);
3907ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  String::cast(result)->set_hash_field(String::kEmptyHashField);
3908e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(size, HeapObject::cast(result)->Size());
390943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
391043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
391143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
391243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3913a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateEmptyFixedArray() {
391443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int size = FixedArray::SizeFor(0);
3915a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
39163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
39173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation =
3918303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
3919a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
3920303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
392143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize the object.
3922a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(fixed_array_map());
3923a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  FixedArray::cast(result)->set_length(0);
392443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
392543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
392643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3927e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3928a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateEmptyExternalArray(
3929a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    ExternalArrayType array_type) {
39304e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  return AllocateExternalArray(0, array_type, NULL, TENURED);
39314e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
39324e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
393343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3934a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::CopyAndTenureFixedCOWArray(FixedArray* src) {
39352904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (!InNewSpace(src)) {
39362904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    return src;
39372904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
39382904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
39392904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  int len = src->length();
3940a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* obj;
39413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
39423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRawFixedArray(len, TENURED);
3943a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return allocation;
39442904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
3945a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  obj->set_map_no_write_barrier(fixed_array_map());
39462904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  FixedArray* result = FixedArray::cast(obj);
39472904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  result->set_length(len);
39482904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
39492904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // Copy the content
39502904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  DisallowHeapAllocation no_gc;
39512904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
39522904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
39532904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
39542904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // TODO(mvstanton): The map is set twice because of protection against calling
39552904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // set() on a COW FixedArray. Issue v8:3221 created to track this, and
39562904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // we might then be able to remove this whole method.
39572904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  HeapObject::cast(obj)->set_map_no_write_barrier(fixed_cow_array_map());
39582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  return result;
39592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
39602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
39612904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
3962a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateEmptyFixedTypedArray(
3963a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    ExternalArrayType array_type) {
3964895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return AllocateFixedTypedArray(0, array_type, TENURED);
3965895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
3966895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
3967895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
3968a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
39695a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  int len = src->length();
3970a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* obj;
39713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
39723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED);
3973a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return allocation;
3974303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
3975ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (InNewSpace(obj)) {
3976a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    obj->set_map_no_write_barrier(map);
39773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    CopyBlock(obj->address() + kPointerSize, src->address() + kPointerSize,
39784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org              FixedArray::SizeFor(len) - kPointerSize);
39795a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    return obj;
39805a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
3981a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  obj->set_map_no_write_barrier(map);
39825a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  FixedArray* result = FixedArray::cast(obj);
39835a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  result->set_length(len);
3984b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
39855a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Copy the content
398679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
3987b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
39885a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
39895a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return result;
39905a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
39915a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
39925a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
3993a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src,
3994a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                                   Map* map) {
39952c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  int len = src->length();
3996a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* obj;
39973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
39983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRawFixedDoubleArray(len, NOT_TENURED);
3999a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return allocation;
40002c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  }
4001a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  obj->set_map_no_write_barrier(map);
40023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  CopyBlock(obj->address() + FixedDoubleArray::kLengthOffset,
40033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            src->address() + FixedDoubleArray::kLengthOffset,
40043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset);
40052c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  return obj;
40062c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org}
40072c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
40082c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
4009a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src,
4010a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                                    Map* map) {
4011a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* obj;
4012196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (src->is_extended_layout()) {
4013196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    ConstantPoolArray::NumberOfEntries small(src,
40143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                             ConstantPoolArray::SMALL_SECTION);
40153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ConstantPoolArray::NumberOfEntries extended(
40163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        src, ConstantPoolArray::EXTENDED_SECTION);
4017196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    AllocationResult allocation =
4018196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        AllocateExtendedConstantPoolArray(small, extended);
4019196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if (!allocation.To(&obj)) return allocation;
4020196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  } else {
4021196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    ConstantPoolArray::NumberOfEntries small(src,
40223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                             ConstantPoolArray::SMALL_SECTION);
4023196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    AllocationResult allocation = AllocateConstantPoolArray(small);
4024a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return allocation;
4025a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
4026a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  obj->set_map_no_write_barrier(map);
40273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  CopyBlock(obj->address() + ConstantPoolArray::kFirstEntryOffset,
40283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            src->address() + ConstantPoolArray::kFirstEntryOffset,
40293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            src->size() - ConstantPoolArray::kFirstEntryOffset);
4030a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  return obj;
4031a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org}
4032a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
4033a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
4034a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateRawFixedArray(int length,
4035a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                             PretenureFlag pretenure) {
40360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  if (length < 0 || length > FixedArray::kMaxLength) {
4037a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
40380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
4039c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int size = FixedArray::SizeFor(length);
40403d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure);
40410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
40423d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  return AllocateRaw(size, space, OLD_POINTER_SPACE);
4043c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
4044c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
4045c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
4046a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateFixedArrayWithFiller(int length,
4047a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                                    PretenureFlag pretenure,
4048a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                                    Object* filler) {
4049e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(length >= 0);
4050e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(empty_fixed_array()->IsFixedArray());
4051cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  if (length == 0) return empty_fixed_array();
4052c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
4053e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!InNewSpace(filler));
4054a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
40553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
40563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRawFixedArray(length, pretenure);
4057a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
4058303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
40590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
4060a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(fixed_array_map());
406143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FixedArray* array = FixedArray::cast(result);
406243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  array->set_length(length);
4063c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  MemsetPointer(array->data_start(), filler, length);
406443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return array;
406543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
406643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
406743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4068a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
4069cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  return AllocateFixedArrayWithFiller(length, pretenure, undefined_value());
4070c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
4071c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
4072c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
4073a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateUninitializedFixedArray(int length) {
4074ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (length == 0) return empty_fixed_array();
4075ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
4076a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* obj;
40773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
40783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRawFixedArray(length, NOT_TENURED);
4079a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&obj)) return allocation;
4080303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
4081ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
4082a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  obj->set_map_no_write_barrier(fixed_array_map());
4083ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  FixedArray::cast(obj)->set_length(length);
4084ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return obj;
4085ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
4086ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
4087ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
4088a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateUninitializedFixedDoubleArray(
40893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    int length, PretenureFlag pretenure) {
409065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  if (length == 0) return empty_fixed_array();
40916d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
4092a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* elements;
4093a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation = AllocateRawFixedDoubleArray(length, pretenure);
4094a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&elements)) return allocation;
4095fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
4096fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  elements->set_map_no_write_barrier(fixed_double_array_map());
4097a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  FixedDoubleArray::cast(elements)->set_length(length);
4098fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  return elements;
4099fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
4100fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
4101fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
4102a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateRawFixedDoubleArray(int length,
4103a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                                   PretenureFlag pretenure) {
41046d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (length < 0 || length > FixedDoubleArray::kMaxLength) {
4105a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
41066d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
41076d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  int size = FixedDoubleArray::SizeFor(length);
4108ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com#ifndef V8_HOST_ARCH_64_BIT
4109ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  size += kPointerSize;
4110ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com#endif
41113d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
41126d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
4113ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  HeapObject* object;
41143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
41153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
4116a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&object)) return allocation;
4117ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
4118ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
4119ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  return EnsureDoubleAligned(this, object, size);
41206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
41216d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
41226d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
4123196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgAllocationResult Heap::AllocateConstantPoolArray(
41243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    const ConstantPoolArray::NumberOfEntries& small) {
4125196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK(small.are_in_range(0, ConstantPoolArray::kMaxSmallEntriesPerType));
4126196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  int size = ConstantPoolArray::SizeFor(small);
4127a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org#ifndef V8_HOST_ARCH_64_BIT
4128a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  size += kPointerSize;
4129a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org#endif
4130c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED);
4131a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
4132a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  HeapObject* object;
41333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
41343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, OLD_POINTER_SPACE);
4135a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&object)) return allocation;
4136a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
4137a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  object = EnsureDoubleAligned(this, object, size);
4138a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  object->set_map_no_write_barrier(constant_pool_array_map());
4139a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
4140a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);
4141196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  constant_pool->Init(small);
4142196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  constant_pool->ClearPtrEntries(isolate());
4143196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return constant_pool;
4144196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
4145196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
4146196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
4147196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgAllocationResult Heap::AllocateExtendedConstantPoolArray(
4148196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    const ConstantPoolArray::NumberOfEntries& small,
4149196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    const ConstantPoolArray::NumberOfEntries& extended) {
4150196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK(small.are_in_range(0, ConstantPoolArray::kMaxSmallEntriesPerType));
4151196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK(extended.are_in_range(0, kMaxInt));
4152196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  int size = ConstantPoolArray::SizeForExtended(small, extended);
4153196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#ifndef V8_HOST_ARCH_64_BIT
4154196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  size += kPointerSize;
4155196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#endif
4156196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED);
4157196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
4158196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  HeapObject* object;
41593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
41603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = AllocateRaw(size, space, OLD_POINTER_SPACE);
4161196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if (!allocation.To(&object)) return allocation;
41629ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  }
4163196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  object = EnsureDoubleAligned(this, object, size);
4164196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  object->set_map_no_write_barrier(constant_pool_array_map());
4165196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
4166196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);
4167196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  constant_pool->InitExtended(small, extended);
4168196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  constant_pool->ClearPtrEntries(isolate());
4169a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  return constant_pool;
4170a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org}
4171a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
4172a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
4173a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateEmptyConstantPoolArray() {
4174196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ConstantPoolArray::NumberOfEntries small(0, 0, 0, 0);
4175196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  int size = ConstantPoolArray::SizeFor(small);
4176a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
41773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
41783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation =
41799ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org        AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
4180a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
41819ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  }
4182a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(constant_pool_array_map());
4183196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ConstantPoolArray::cast(result)->Init(small);
41849ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  return result;
41859ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org}
41869ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
41879ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
4188a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateSymbol() {
41894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Statically ensure that it is safe to allocate symbols in paged spaces.
4190ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  STATIC_ASSERT(Symbol::kSize <= Page::kMaxRegularHeapObjectSize);
41914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4192a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* result;
4193a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation =
4194f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      AllocateRaw(Symbol::kSize, OLD_POINTER_SPACE, OLD_POINTER_SPACE);
4195a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (!allocation.To(&result)) return allocation;
41964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4197a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->set_map_no_write_barrier(symbol_map());
41984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
41994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Generate a random hash value.
42004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int hash;
42014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int attempts = 0;
42024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  do {
4203c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    hash = isolate()->random_number_generator()->NextInt() & Name::kHashBitMask;
42044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    attempts++;
42054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } while (hash == 0 && attempts < 30);
42064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (hash == 0) hash = 1;  // never return 0
42074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
42083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Symbol::cast(result)
42093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      ->set_hash_field(Name::kIsNotArrayIndexMask | (hash << Name::kHashShift));
4210f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Symbol::cast(result)->set_name(undefined_value());
42110cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  Symbol::cast(result)->set_flags(Smi::FromInt(0));
42124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4213e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!Symbol::cast(result)->is_private());
42144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return result;
42154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
42164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
42174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4218a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgAllocationResult Heap::AllocateStruct(InstanceType type) {
421943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Map* map;
422043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (type) {
4221ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#define MAKE_CASE(NAME, Name, name) \
42223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  case NAME##_TYPE:                 \
42233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    map = name##_map();             \
42243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    break;
42253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    STRUCT_LIST(MAKE_CASE)
422643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef MAKE_CASE
422743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
422843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      UNREACHABLE();
4229b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org      return exception();
423043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
423143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int size = map->instance_size();
42323d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED);
4233a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  Struct* result;
42343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
42353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AllocationResult allocation = Allocate(map, space);
4236a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!allocation.To(&result)) return allocation;
4237303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
4238a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  result->InitializeBody(size);
423943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
424043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
424143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
424243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool Heap::IsHeapIterable() {
42449d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  // TODO(hpayer): This function is not correct. Allocation folding in old
42459d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  // space breaks the iterability.
4246a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return new_space_top_after_last_gc_ == new_space()->top();
4247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4250fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgvoid Heap::MakeHeapIterable() {
4251e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(AllowHeapAllocation::IsAllowed());
4252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!IsHeapIterable()) {
4253fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable");
4254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
42559d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  if (mark_compact_collector()->sweeping_in_progress()) {
42569d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    mark_compact_collector()->EnsureSweepingCompleted();
42579d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  }
4258e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsHeapIterable());
4259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
42629865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.orgvoid Heap::IdleMarkCompact(const char* message) {
42639865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org  bool uncommit = false;
42649865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org  if (gc_count_at_last_idle_gc_ == gc_count_) {
42659865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org    // No GC since the last full GC, the mutator is probably not active.
42669865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org    isolate_->compilation_cache()->Clear();
42679865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org    uncommit = true;
42689865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org  }
42699865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org  CollectAllGarbage(kReduceMemoryFootprintMask, message);
42709865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org  gc_idle_time_handler_.NotifyIdleMarkCompact();
42719865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org  gc_count_at_last_idle_gc_ = gc_count_;
42729865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org  if (uncommit) {
42739865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org    new_space_.Shrink();
42749865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org    UncommitFromSpace();
42759865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org  }
42769865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org}
42779865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org
42789865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org
4279a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
42807d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  incremental_marking()->Step(step_size,
42813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                              IncrementalMarking::NO_GC_VIA_STACK_GUARD, true);
42826ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
42836ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  if (incremental_marking()->IsComplete()) {
42849865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org    IdleMarkCompact("idle notification: finalize incremental");
42856ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  }
42866ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org}
42876ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
42886ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
4289a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgbool Heap::WorthActivatingIncrementalMarking() {
4290a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return incremental_marking()->IsStopped() &&
4291a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org         incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull();
4292a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
4293a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
4294a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
4295e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgbool Heap::IdleNotification(int idle_time_in_ms) {
42962b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org  // If incremental marking is off, we do not perform idle notification.
42972b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org  if (!FLAG_incremental_marking) return true;
4298ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  base::ElapsedTimer timer;
4299d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  timer.Start();
4300e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
4301e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      idle_time_in_ms);
4302474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  HistogramTimerScope idle_notification_scope(
4303474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      isolate_->counters()->gc_idle_notification());
4304474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
4305a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  GCIdleTimeHandler::HeapState heap_state;
4306a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  heap_state.contexts_disposed = contexts_disposed_;
4307a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects());
4308a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
4309a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // TODO(ulan): Start incremental marking only for large heaps.
4310d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  heap_state.can_start_incremental_marking =
4311d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org      incremental_marking()->ShouldActivate();
4312a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  heap_state.sweeping_in_progress =
4313a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      mark_compact_collector()->sweeping_in_progress();
4314a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  heap_state.mark_compact_speed_in_bytes_per_ms =
4315a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond());
4316a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>(
4317a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      tracer()->IncrementalMarkingSpeedInBytesPerMillisecond());
4318d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  heap_state.scavenge_speed_in_bytes_per_ms =
4319d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org      static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond());
4320d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  heap_state.available_new_space_memory = new_space_.Available();
4321d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  heap_state.new_space_capacity = new_space_.Capacity();
4322a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  heap_state.new_space_allocation_throughput_in_bytes_per_ms =
4323a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      static_cast<size_t>(
4324a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org          tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond());
4325a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
4326a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  GCIdleTimeAction action =
4327a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state);
4328a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
4329a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  bool result = false;
4330a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  switch (action.type) {
4331d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org    case DONE:
4332d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org      result = true;
4333d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org      break;
4334a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case DO_INCREMENTAL_MARKING:
4335a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (incremental_marking()->IsStopped()) {
4336a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        incremental_marking()->Start();
4337a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      }
4338a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      AdvanceIdleIncrementalMarking(action.parameter);
4339a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
4340a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case DO_FULL_GC: {
43416ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org      HistogramTimerScope scope(isolate_->counters()->gc_context());
43429865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org      if (contexts_disposed_) {
43439865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org        CollectAllGarbage(kReduceMemoryFootprintMask,
43449865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org                          "idle notification: contexts disposed");
43459865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org        gc_idle_time_handler_.NotifyIdleMarkCompact();
43469865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org        gc_count_at_last_idle_gc_ = gc_count_;
43479865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org      } else {
43489865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org        IdleMarkCompact("idle notification: finalize idle round");
43499865d88eda6cb48e94d6408952cf4534fb1976faulan@chromium.org      }
4350a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
4351de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    }
4352a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case DO_SCAVENGE:
4353a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      CollectGarbage(NEW_SPACE, "idle notification: scavenge");
4354a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
4355a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case DO_FINALIZE_SWEEPING:
4356a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      mark_compact_collector()->EnsureSweepingCompleted();
4357a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
4358a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case DO_NOTHING:
4359a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
4360a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  }
4361d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org
4362d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  int actual_time_ms = static_cast<int>(timer.Elapsed().InMilliseconds());
4363d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  if (actual_time_ms <= idle_time_in_ms) {
4364d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org    isolate()->counters()->gc_idle_time_limit_undershot()->AddSample(
4365d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org        idle_time_in_ms - actual_time_ms);
4366d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  } else {
4367d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org    isolate()->counters()->gc_idle_time_limit_overshot()->AddSample(
4368d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org        actual_time_ms - idle_time_in_ms);
4369d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  }
4370d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org
4371ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  if (FLAG_trace_idle_notification) {
4372ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    PrintF("Idle notification: requested idle time %d ms, actual time %d ms [",
4373ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org           idle_time_in_ms, actual_time_ms);
4374ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    action.Print();
4375ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    PrintF("]\n");
4376ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  }
4377a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
43789e2b466e4b4a2026caefa79afe6737f1bad83a19machenbach@chromium.org  contexts_disposed_ = 0;
4379a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return result;
4380ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org}
4381ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
4382ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
438343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
438443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
438543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::Print() {
4386f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return;
4387bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  isolate()->PrintStack(stdout);
43887c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  AllSpaces spaces(this);
43897c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
4390b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    space->Print();
43917c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
439243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
439343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
439443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
439543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ReportCodeStatistics(const char* title) {
439643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF(">>>>>> Code Stats (%s) >>>>>>\n", title);
43973d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  PagedSpace::ResetCodeStatistics(isolate());
439843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We do not look for code in new space, map space, or old space.  If code
439943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // somehow ends up in those spaces, we would miss it here.
440043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  code_space_->CollectCodeStatistics();
440143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  lo_space_->CollectCodeStatistics();
44023d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  PagedSpace::ReportCodeStatistics(isolate());
440343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
440443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
440543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
440643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This function expects that NewSpace's allocated objects histogram is
440743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// populated (via a call to CollectStatistics or else as a side effect of a
440843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// just-completed scavenge collection).
440943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ReportHeapStatistics(const char* title) {
441043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  USE(title);
44113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PrintF(">>>>>> =============== %s (%d) =============== >>>>>>\n", title,
44123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         gc_count_);
4413a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  PrintF("old_generation_allocation_limit_ %" V8_PTR_PREFIX "d\n",
4414a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org         old_generation_allocation_limit_);
441543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
441643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("\n");
441709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles(isolate_));
4418ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->global_handles()->PrintStats();
441943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("\n");
442043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
442143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Heap statistics : ");
4422ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->memory_allocator()->ReportStatistics();
442343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("To space : ");
44245a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  new_space_.ReportStatistics();
44259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  PrintF("Old pointer space : ");
44269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  old_pointer_space_->ReportStatistics();
44279258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  PrintF("Old data space : ");
44289258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  old_data_space_->ReportStatistics();
442943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Code space : ");
443043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  code_space_->ReportStatistics();
443143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Map space : ");
443243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  map_space_->ReportStatistics();
4433defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  PrintF("Cell space : ");
4434defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  cell_space_->ReportStatistics();
4435b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  PrintF("PropertyCell space : ");
443641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  property_cell_space_->ReportStatistics();
443743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Large object space : ");
443843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  lo_space_->ReportStatistics();
443943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF(">>>>>> ========================================= >>>>>>\n");
444043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
444143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
444243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // DEBUG
444343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgbool Heap::Contains(HeapObject* value) { return Contains(value->address()); }
444543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
444643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
444743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::Contains(Address addr) {
44482c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(addr)) return false;
4449f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  return HasBeenSetUp() &&
44503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         (new_space_.ToSpaceContains(addr) ||
44513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          old_pointer_space_->Contains(addr) ||
44523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          old_data_space_->Contains(addr) || code_space_->Contains(addr) ||
44533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          map_space_->Contains(addr) || cell_space_->Contains(addr) ||
44543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          property_cell_space_->Contains(addr) ||
44553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          lo_space_->SlowContains(addr));
445643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
445743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
445843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
445943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::InSpace(HeapObject* value, AllocationSpace space) {
446043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return InSpace(value->address(), space);
446143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
446243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
446343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
446443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Heap::InSpace(Address addr, AllocationSpace space) {
44652c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(addr)) return false;
4466f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!HasBeenSetUp()) return false;
446743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
446843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (space) {
446943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case NEW_SPACE:
44705a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      return new_space_.ToSpaceContains(addr);
44719258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
44729258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return old_pointer_space_->Contains(addr);
44739258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
44749258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return old_data_space_->Contains(addr);
447543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case CODE_SPACE:
447643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return code_space_->Contains(addr);
447743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case MAP_SPACE:
447843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return map_space_->Contains(addr);
4479defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    case CELL_SPACE:
4480defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      return cell_space_->Contains(addr);
448141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_SPACE:
448241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      return property_cell_space_->Contains(addr);
448343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case LO_SPACE:
448443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return lo_space_->SlowContains(addr);
4485a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    case INVALID_SPACE:
4486a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      break;
448743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4488a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  UNREACHABLE();
448943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
449043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
449143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
449243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4493c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
449443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::Verify() {
4495c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  CHECK(HasBeenSetUp());
4496e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate());
449743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->Verify();
4499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4500474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (mark_compact_collector()->sweeping_in_progress()) {
4501474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    // We have to wait here for the sweeper threads to have an iterable heap.
4502474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    mark_compact_collector()->EnsureSweepingCompleted();
4503474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
4504474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
450543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  VerifyPointersVisitor visitor;
4506c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  IterateRoots(&visitor, VISIT_ONLY_STRONG);
450743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4508f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  VerifySmisVisitor smis_visitor;
4509f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  IterateSmiRoots(&smis_visitor);
4510f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
4511defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  new_space_.Verify();
4512defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
4513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  old_pointer_space_->Verify(&visitor);
4514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  map_space_->Verify(&visitor);
451530ce411529579186181838984710b0b0980857aaricow@chromium.org
451630ce411529579186181838984710b0b0980857aaricow@chromium.org  VerifyPointersVisitor no_dirty_regions_visitor;
451730ce411529579186181838984710b0b0980857aaricow@chromium.org  old_data_space_->Verify(&no_dirty_regions_visitor);
451830ce411529579186181838984710b0b0980857aaricow@chromium.org  code_space_->Verify(&no_dirty_regions_visitor);
451930ce411529579186181838984710b0b0980857aaricow@chromium.org  cell_space_->Verify(&no_dirty_regions_visitor);
452041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  property_cell_space_->Verify(&no_dirty_regions_visitor);
4521defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
4522defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  lo_space_->Verify();
4523f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
4524c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
452543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
452643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
452743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::ZapFromSpace() {
4528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  NewSpacePageIterator it(new_space_.FromSpaceStart(),
4529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          new_space_.FromSpaceEnd());
4530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
4531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    NewSpacePage* page = it.next();
4532ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    for (Address cursor = page->area_start(), limit = page->area_end();
45333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         cursor < limit; cursor += kPointerSize) {
4534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Memory::Address_at(cursor) = kFromSpaceZapValue;
4535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
453643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
453743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
453843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
453943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid Heap::IterateAndMarkPointersToFromSpace(Address start, Address end,
4541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                             ObjectSlotCallback callback) {
454230ce411529579186181838984710b0b0980857aaricow@chromium.org  Address slot_address = start;
4543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // We are not collecting slots on new space objects during mutation
4545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // thus we have to scan for pointers to evacuation candidates when we
4546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // promote objects. But we should not record any slots in non-black
4547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // objects. Grey object's slots would be rescanned.
4548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // White object might not survive until the end of collection
4549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // it would be a violation of the invariant to record it's slots.
4550c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool record_slots = false;
4551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (incremental_marking()->IsCompacting()) {
4552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(HeapObject::FromAddress(start));
4553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    record_slots = Marking::IsBlack(mark_bit);
4554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
455530ce411529579186181838984710b0b0980857aaricow@chromium.org
455630ce411529579186181838984710b0b0980857aaricow@chromium.org  while (slot_address < end) {
455730ce411529579186181838984710b0b0980857aaricow@chromium.org    Object** slot = reinterpret_cast<Object**>(slot_address);
4558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* object = *slot;
4559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the store buffer becomes overfull we mark pages as being exempt from
4560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // the store buffer.  These pages are scanned to find pointers that point
4561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // to the new space.  In that case we may hit newly promoted objects and
4562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // fix the pointers before the promotion queue gets to them.  Thus the 'if'.
4563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (object->IsHeapObject()) {
4564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (Heap::InFromSpace(object)) {
4565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        callback(reinterpret_cast<HeapObject**>(slot),
4566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 HeapObject::cast(object));
4567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        Object* new_object = *slot;
4568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (InNewSpace(new_object)) {
4569e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          SLOW_DCHECK(Heap::InToSpace(new_object));
4570e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          SLOW_DCHECK(new_object->IsHeapObject());
4571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          store_buffer_.EnterDirectlyIntoStoreBuffer(
4572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com              reinterpret_cast<Address>(slot));
4573c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
4574e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        SLOW_DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_object));
4575c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else if (record_slots &&
4576c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 MarkCompactCollector::IsOnEvacuationCandidate(object)) {
4577c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        mark_compact_collector()->RecordSlot(slot, slot, object);
457843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
457930ce411529579186181838984710b0b0980857aaricow@chromium.org    }
458030ce411529579186181838984710b0b0980857aaricow@chromium.org    slot_address += kPointerSize;
458130ce411529579186181838984710b0b0980857aaricow@chromium.org  }
458230ce411529579186181838984710b0b0980857aaricow@chromium.org}
458330ce411529579186181838984710b0b0980857aaricow@chromium.org
458430ce411529579186181838984710b0b0980857aaricow@chromium.org
4585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG
4586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comtypedef bool (*CheckStoreBufferFilter)(Object** addr);
458730ce411529579186181838984710b0b0980857aaricow@chromium.org
458830ce411529579186181838984710b0b0980857aaricow@chromium.org
4589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool IsAMapPointerAddress(Object** addr) {
4590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  uintptr_t a = reinterpret_cast<uintptr_t>(addr);
4591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int mod = a % Map::kSize;
4592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return mod >= Map::kPointerFieldsBeginOffset &&
4593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         mod < Map::kPointerFieldsEndOffset;
459430ce411529579186181838984710b0b0980857aaricow@chromium.org}
459530ce411529579186181838984710b0b0980857aaricow@chromium.org
459630ce411529579186181838984710b0b0980857aaricow@chromium.org
45973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgbool EverythingsAPointer(Object** addr) { return true; }
459830ce411529579186181838984710b0b0980857aaricow@chromium.org
459930ce411529579186181838984710b0b0980857aaricow@chromium.org
46003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic void CheckStoreBuffer(Heap* heap, Object** current, Object** limit,
4601c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Object**** store_buffer_position,
4602c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Object*** store_buffer_top,
4603c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             CheckStoreBufferFilter filter,
4604c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Address special_garbage_start,
4605c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             Address special_garbage_end) {
4606c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Map* free_space_map = heap->free_space_map();
46073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (; current < limit; current++) {
4608c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* o = *current;
4609c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Address current_address = reinterpret_cast<Address>(current);
4610c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Skip free space.
4611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (o == free_space_map) {
4612c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Address current_address = reinterpret_cast<Address>(current);
4613c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      FreeSpace* free_space =
4614c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          FreeSpace::cast(HeapObject::FromAddress(current_address));
4615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int skip = free_space->Size();
4616e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(current_address + skip <= reinterpret_cast<Address>(limit));
4617e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(skip > 0);
4618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current_address += skip - kPointerSize;
4619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current = reinterpret_cast<Object**>(current_address);
4620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      continue;
4621c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
4622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Skip the current linear allocation space between top and limit which is
4623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // unmarked with the free space map, but can contain junk.
4624c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (current_address == special_garbage_start &&
4625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        special_garbage_end != special_garbage_start) {
4626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current_address = special_garbage_end - kPointerSize;
4627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current = reinterpret_cast<Object**>(current_address);
4628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      continue;
4629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
4630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!(*filter)(current)) continue;
4631e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(current_address < special_garbage_start ||
4632c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           current_address >= special_garbage_end);
4633e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(reinterpret_cast<uintptr_t>(o) != kFreeListZapValue);
4634c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // We have to check that the pointer does not point into new space
4635c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // without trying to cast it to a heap object since the hash field of
4636c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a string can contain values like 1 and 3 which are tagged null
4637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // pointers.
4638c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!heap->InNewSpace(o)) continue;
4639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    while (**store_buffer_position < current &&
4640c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           *store_buffer_position < store_buffer_top) {
4641c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      (*store_buffer_position)++;
4642c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
4643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (**store_buffer_position != current ||
4644c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        *store_buffer_position == store_buffer_top) {
4645c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object** obj_start = current;
4646c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      while (!(*obj_start)->IsMap()) obj_start--;
4647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      UNREACHABLE();
464830ce411529579186181838984710b0b0980857aaricow@chromium.org    }
464930ce411529579186181838984710b0b0980857aaricow@chromium.org  }
465030ce411529579186181838984710b0b0980857aaricow@chromium.org}
465130ce411529579186181838984710b0b0980857aaricow@chromium.org
465230ce411529579186181838984710b0b0980857aaricow@chromium.org
4653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Check that the store buffer contains all intergenerational pointers by
4654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// scanning a page and ensuring that all pointers to young space are in the
4655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// store buffer.
4656c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::OldPointerSpaceCheckStoreBuffer() {
4657c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  OldSpace* space = old_pointer_space();
4658c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PageIterator pages(space);
465930ce411529579186181838984710b0b0980857aaricow@chromium.org
4660c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->SortUniq();
466130ce411529579186181838984710b0b0980857aaricow@chromium.org
4662c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (pages.has_next()) {
4663c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* page = pages.next();
4664ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Object** current = reinterpret_cast<Object**>(page->area_start());
466530ce411529579186181838984710b0b0980857aaricow@chromium.org
4666ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Address end = page->area_end();
466730ce411529579186181838984710b0b0980857aaricow@chromium.org
4668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object*** store_buffer_position = store_buffer()->Start();
4669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object*** store_buffer_top = store_buffer()->Top();
467030ce411529579186181838984710b0b0980857aaricow@chromium.org
4671c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object** limit = reinterpret_cast<Object**>(end);
46723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    CheckStoreBuffer(this, current, limit, &store_buffer_position,
46733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                     store_buffer_top, &EverythingsAPointer, space->top(),
4674c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     space->limit());
467530ce411529579186181838984710b0b0980857aaricow@chromium.org  }
467630ce411529579186181838984710b0b0980857aaricow@chromium.org}
467730ce411529579186181838984710b0b0980857aaricow@chromium.org
467830ce411529579186181838984710b0b0980857aaricow@chromium.org
4679c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::MapSpaceCheckStoreBuffer() {
4680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MapSpace* space = map_space();
4681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PageIterator pages(space);
468230ce411529579186181838984710b0b0980857aaricow@chromium.org
4683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->SortUniq();
468430ce411529579186181838984710b0b0980857aaricow@chromium.org
4685c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (pages.has_next()) {
4686c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* page = pages.next();
4687ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Object** current = reinterpret_cast<Object**>(page->area_start());
468830ce411529579186181838984710b0b0980857aaricow@chromium.org
4689ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Address end = page->area_end();
469030ce411529579186181838984710b0b0980857aaricow@chromium.org
4691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object*** store_buffer_position = store_buffer()->Start();
4692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object*** store_buffer_top = store_buffer()->Top();
469330ce411529579186181838984710b0b0980857aaricow@chromium.org
4694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object** limit = reinterpret_cast<Object**>(end);
46953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    CheckStoreBuffer(this, current, limit, &store_buffer_position,
46963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                     store_buffer_top, &IsAMapPointerAddress, space->top(),
4697c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     space->limit());
469830ce411529579186181838984710b0b0980857aaricow@chromium.org  }
469943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
470043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
470143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4702c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::LargeObjectSpaceCheckStoreBuffer() {
4703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  LargeObjectIterator it(lo_space());
4704c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
4705c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // We only have code, sequential strings, or fixed arrays in large
4706c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // object space, and only fixed arrays can possibly contain pointers to
4707c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // the young generation.
4708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (object->IsFixedArray()) {
4709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object*** store_buffer_position = store_buffer()->Start();
4710c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object*** store_buffer_top = store_buffer()->Top();
4711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object** current = reinterpret_cast<Object**>(object->address());
4712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object** limit =
4713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          reinterpret_cast<Object**>(object->address() + object->Size());
47143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      CheckStoreBuffer(this, current, limit, &store_buffer_position,
47153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                       store_buffer_top, &EverythingsAPointer, NULL, NULL);
471671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org    }
471743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
471843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
4719c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
472043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
472143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4722c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) {
4723c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  IterateStrongRoots(v, mode);
4724b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  IterateWeakRoots(v, mode);
4725b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
4726b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4727b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4728b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) {
47294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  v->VisitPointer(reinterpret_cast<Object**>(&roots_[kStringTableRootIndex]));
47304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  v->Synchronize(VisitorSynchronization::kStringTable);
47313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (mode != VISIT_ALL_IN_SCAVENGE && mode != VISIT_ALL_IN_SWEEP_NEWSPACE) {
473213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    // Scavenge collections have special processing for this.
4733ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    external_string_table_.Iterate(v);
473413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
473564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kExternalStringsTable);
473643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
473743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
473843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4739f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid Heap::IterateSmiRoots(ObjectVisitor* v) {
47404452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  // Acquire execution access since we are going to read stack limit values.
47414452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  ExecutionAccess access(isolate());
4742f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  v->VisitPointers(&roots_[kSmiRootsStart], &roots_[kRootListLength]);
4743f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  v->Synchronize(VisitorSynchronization::kSmiRootList);
4744f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
4745f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
4746f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
4747c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
474868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
474964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kStrongRootList);
475043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4751e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  v->VisitPointer(bit_cast<Object**>(&hidden_string_));
47524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  v->Synchronize(VisitorSynchronization::kInternalizedString);
475343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4754ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->bootstrapper()->Iterate(v);
475564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kBootstrapper);
4756ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->Iterate(v);
475764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kTop);
47583d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Relocatable::Iterate(isolate_, v);
475964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kRelocatable);
476065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
47614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (isolate_->deoptimizer_data() != NULL) {
47624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    isolate_->deoptimizer_data()->Iterate(v);
47634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
476464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kDebug);
4765ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->compilation_cache()->Iterate(v);
476664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kCompilationCache);
476743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
476843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate over local handles in handle scopes.
4769ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->handle_scope_implementer()->Iterate(v);
4770304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  isolate_->IterateDeferredHandles(v);
477164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kHandleScope);
477243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
477313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Iterate over the builtin code objects and code stubs in the
477413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // heap. Note that it is not necessary to iterate over code objects
477513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // on scavenge collections.
4776c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (mode != VISIT_ALL_IN_SCAVENGE) {
4777ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->builtins()->IterateBuiltins(v);
477813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
477964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kBuiltins);
478043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
478143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate over global handles.
4782c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  switch (mode) {
4783c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    case VISIT_ONLY_STRONG:
4784c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      isolate_->global_handles()->IterateStrongRoots(v);
4785c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      break;
4786c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    case VISIT_ALL_IN_SCAVENGE:
4787e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v);
4788c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      break;
4789c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    case VISIT_ALL_IN_SWEEP_NEWSPACE:
4790c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    case VISIT_ALL:
4791c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      isolate_->global_handles()->IterateAllRoots(v);
4792c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      break;
4793c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
479464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kGlobalHandles);
479543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4796594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Iterate over eternal handles.
4797594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (mode == VISIT_ALL_IN_SCAVENGE) {
4798594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    isolate_->eternal_handles()->IterateNewSpaceRoots(v);
4799594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else {
4800594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    isolate_->eternal_handles()->IterateAllRoots(v);
4801594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
4802594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v->Synchronize(VisitorSynchronization::kEternalHandles);
4803594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
480443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate over pointers being held by inactive threads.
4805ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->thread_manager()->Iterate(v);
480664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  v->Synchronize(VisitorSynchronization::kThreadManager);
4807b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4808b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Iterate over the pointers the Serialization/Deserialization code is
4809b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // holding.
4810b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // During garbage collection this keeps the partial snapshot cache alive.
4811b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // During deserialization of the startup snapshot this creates the partial
4812b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // snapshot cache and deserializes the objects it refers to.  During
4813b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // serialization this does nothing, since the partial snapshot cache is
4814b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // empty.  However the next thing we do is create the partial snapshot,
4815b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // filling up the partial snapshot cache with objects it needs as we go.
48163d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  SerializerDeserializer::Iterate(isolate_, v);
4817b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // We don't do a v->Synchronize call here, because in debug mode that will
4818b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // output a flag to the snapshot.  However at this point the serializer and
4819b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // deserializer are deliberately a little unsynchronized (see above) so the
4820b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // checking of the sync flag in the snapshot would fail.
482143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
482243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
482343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
482443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// TODO(1236194): Since the heap size is configurable on the command line
482543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and through the API, we should gracefully handle the case that the heap
482643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// size is not big enough to fit all the initial objects.
48273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgbool Heap::ConfigureHeap(int max_semi_space_size, int max_old_space_size,
48283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                         int max_executable_size, size_t code_range_size) {
4829f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (HasBeenSetUp()) return false;
483043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48313c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  // Overwrite default configuration.
48323c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (max_semi_space_size > 0) {
48333c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    max_semi_space_size_ = max_semi_space_size * MB;
48343c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
48353c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (max_old_space_size > 0) {
48363c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    max_old_generation_size_ = max_old_space_size * MB;
48373c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
48383c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (max_executable_size > 0) {
48393c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    max_executable_size_ = max_executable_size * MB;
48403c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
48413c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
4842c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  // If max space size flags are specified overwrite the configuration.
48433c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (FLAG_max_semi_space_size > 0) {
48443c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    max_semi_space_size_ = FLAG_max_semi_space_size * MB;
4845c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  }
4846c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  if (FLAG_max_old_space_size > 0) {
48473c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    max_old_generation_size_ = FLAG_max_old_space_size * MB;
4848c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  }
4849c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  if (FLAG_max_executable_size > 0) {
48503c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    max_executable_size_ = FLAG_max_executable_size * MB;
4851c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  }
4852c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
4853efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  if (FLAG_stress_compaction) {
4854efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org    // This will cause more frequent GCs when stressing.
48553c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    max_semi_space_size_ = Page::kPageSize;
4856c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
48573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
4858975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  if (Snapshot::HaveASnapshotToStartFrom()) {
48593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // If we are using a snapshot we always reserve the default amount
48603811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // of memory for each semispace because code in the snapshot has
48613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // write-barrier code that relies on the size and alignment of new
48623811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // space.  We therefore cannot use a larger max semispace size
48633811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // than the default reserved semispace size.
48643c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    if (max_semi_space_size_ > reserved_semispace_size_) {
48653c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      max_semi_space_size_ = reserved_semispace_size_;
4866c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (FLAG_trace_gc) {
48673c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org        PrintPID("Max semi-space size cannot be more than %d kbytes\n",
4868657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org                 reserved_semispace_size_ >> 10);
4869c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
48703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
48713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  } else {
48723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // If we are not using snapshots we reserve space for the actual
48733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    // max semispace size.
48743c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    reserved_semispace_size_ = max_semi_space_size_;
487501fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  }
487601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
487701fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // The max executable size must be less than or equal to the max old
487801fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // generation size.
487901fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  if (max_executable_size_ > max_old_generation_size_) {
488001fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org    max_executable_size_ = max_old_generation_size_;
488101fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  }
488243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
488343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The new space size must be a power of two to support single-bit testing
488443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for containment.
488521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  max_semi_space_size_ =
488621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      base::bits::RoundUpToPowerOfTwo32(max_semi_space_size_);
488721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  reserved_semispace_size_ =
488821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      base::bits::RoundUpToPowerOfTwo32(reserved_semispace_size_);
48893c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
48903c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (FLAG_min_semi_space_size > 0) {
48913c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    int initial_semispace_size = FLAG_min_semi_space_size * MB;
48923c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    if (initial_semispace_size > max_semi_space_size_) {
48933c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      initial_semispace_size_ = max_semi_space_size_;
48943c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      if (FLAG_trace_gc) {
48953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        PrintPID(
48963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            "Min semi-space size cannot be more than the maximum"
48973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            "semi-space size of %d MB\n",
48983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            max_semi_space_size_);
48993c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      }
49003c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    } else {
49013c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      initial_semispace_size_ = initial_semispace_size;
49023c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    }
49033c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
49043c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
49053c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  initial_semispace_size_ = Min(initial_semispace_size_, max_semi_space_size_);
49061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
4907c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The old generation is paged and needs at least one page for each space.
4908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
49093c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  max_old_generation_size_ =
49103c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      Max(static_cast<intptr_t>(paged_space_count * Page::kPageSize),
49113c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org          max_old_generation_size_);
491243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4913e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  // We rely on being able to allocate new arrays in paged spaces.
4914e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(Page::kMaxRegularHeapObjectSize >=
4915e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org         (JSArray::kSize +
4916e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org          FixedArray::SizeFor(JSObject::kInitialMaxFastElementArray) +
4917e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org          AllocationMemento::kSize));
4918e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org
49193c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  code_range_size_ = code_range_size * MB;
49205b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org
4921ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  configured_ = true;
492243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
492343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
492443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
492543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgbool Heap::ConfigureHeapDefault() { return ConfigureHeap(0, 0, 0, 0); }
49277276f14ca716596e0a0d17539516370c1f453847kasper.lund
49287276f14ca716596e0a0d17539516370c1f453847kasper.lund
4929c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.orgvoid Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
49300b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  *stats->start_marker = HeapStats::kStartMarker;
49310b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  *stats->end_marker = HeapStats::kEndMarker;
4932f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  *stats->new_space_size = new_space_.SizeAsInt();
4933f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org  *stats->new_space_capacity = static_cast<int>(new_space_.Capacity());
49342c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->old_pointer_space_size = old_pointer_space_->SizeOfObjects();
4935ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->old_pointer_space_capacity = old_pointer_space_->Capacity();
49362c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->old_data_space_size = old_data_space_->SizeOfObjects();
4937ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->old_data_space_capacity = old_data_space_->Capacity();
49382c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->code_space_size = code_space_->SizeOfObjects();
4939ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->code_space_capacity = code_space_->Capacity();
49402c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->map_space_size = map_space_->SizeOfObjects();
4941ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->map_space_capacity = map_space_->Capacity();
49422c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  *stats->cell_space_size = cell_space_->SizeOfObjects();
4943ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->cell_space_capacity = cell_space_->Capacity();
494441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  *stats->property_cell_space_size = property_cell_space_->SizeOfObjects();
494541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  *stats->property_cell_space_capacity = property_cell_space_->Capacity();
4946ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  *stats->lo_space_size = lo_space_->Size();
4947ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->global_handles()->RecordStats(stats);
4948ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  *stats->memory_allocator_size = isolate()->memory_allocator()->Size();
4949c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  *stats->memory_allocator_capacity =
4950ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate()->memory_allocator()->Size() +
4951ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate()->memory_allocator()->Available();
49525de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  *stats->os_error = base::OS::GetLastError();
49533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  isolate()->memory_allocator()->Available();
4954c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  if (take_snapshot) {
49557c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    HeapIterator iterator(this);
49563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    for (HeapObject* obj = iterator.next(); obj != NULL;
4957c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org         obj = iterator.next()) {
4958c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org      InstanceType type = obj->map()->instance_type();
4959e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(0 <= type && type <= LAST_TYPE);
4960c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org      stats->objects_per_type[type]++;
4961c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org      stats->size_per_type[type] += obj->Size();
4962c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    }
4963c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  }
49646012123a2f016c2ab333c2de98d0debd3966056bager@chromium.org}
49656012123a2f016c2ab333c2de98d0debd3966056bager@chromium.org
49666012123a2f016c2ab333c2de98d0debd3966056bager@chromium.org
4967659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgintptr_t Heap::PromotedSpaceSizeOfObjects() {
49683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  return old_pointer_space_->SizeOfObjects() +
49693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         old_data_space_->SizeOfObjects() + code_space_->SizeOfObjects() +
49703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         map_space_->SizeOfObjects() + cell_space_->SizeOfObjects() +
49713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         property_cell_space_->SizeOfObjects() + lo_space_->SizeOfObjects();
4972659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
4973659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
4974659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
49757ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.orgint64_t Heap::PromotedExternalMemorySize() {
49763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (amount_of_external_allocated_memory_ <=
49773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      amount_of_external_allocated_memory_at_last_global_gc_)
49783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    return 0;
49793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  return amount_of_external_allocated_memory_ -
49803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         amount_of_external_allocated_memory_at_last_global_gc_;
49817276f14ca716596e0a0d17539516370c1f453847kasper.lund}
49827276f14ca716596e0a0d17539516370c1f453847kasper.lund
49837d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
4984c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.orgintptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size,
4985c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org                                            int freed_global_handles) {
4986c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  const int kMaxHandles = 1000;
4987c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  const int kMinHandles = 100;
4988c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  double min_factor = 1.1;
4989c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  double max_factor = 4;
4990c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  // We set the old generation growing factor to 2 to grow the heap slower on
4991c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  // memory-constrained devices.
4992c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
4993c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    max_factor = 2;
4994c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  }
4995c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  // If there are many freed global handles, then the next full GC will
4996c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  // likely collect a lot of garbage. Choose the heap growing factor
4997c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  // depending on freed global handles.
4998c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  // TODO(ulan, hpayer): Take into account mutator utilization.
4999c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  double factor;
5000c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  if (freed_global_handles <= kMinHandles) {
5001c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    factor = max_factor;
5002c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  } else if (freed_global_handles >= kMaxHandles) {
5003c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    factor = min_factor;
5004c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  } else {
5005c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    // Compute factor using linear interpolation between points
5006c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    // (kMinHandles, max_factor) and (kMaxHandles, min_factor).
5007c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    factor = max_factor -
5008c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org             (freed_global_handles - kMinHandles) * (max_factor - min_factor) /
50093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                 (kMaxHandles - kMinHandles);
5010c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  }
5011c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
5012c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  if (FLAG_stress_compaction ||
5013c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org      mark_compact_collector()->reduce_memory_footprint_) {
5014c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org    factor = min_factor;
5015c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  }
5016c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
5017c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  intptr_t limit = static_cast<intptr_t>(old_gen_size * factor);
5018c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  limit = Max(limit, kMinimumOldGenerationAllocationLimit);
5019c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  limit += new_space_.Capacity();
5020c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
5021c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  return Min(limit, halfway_to_the_max);
5022c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org}
5023c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
5024c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org
5025b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid Heap::EnableInlineAllocation() {
5026ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  if (!inline_allocation_disabled_) return;
5027b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  inline_allocation_disabled_ = false;
5028b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
5029b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // Update inline allocation limit for new space.
5030b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  new_space()->UpdateInlineAllocationLimit(0);
5031b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
5032b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
5033b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
5034b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid Heap::DisableInlineAllocation() {
5035ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  if (inline_allocation_disabled_) return;
5036b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  inline_allocation_disabled_ = true;
5037b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
5038b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // Update inline allocation limit for new space.
5039b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  new_space()->UpdateInlineAllocationLimit(0);
5040b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
5041b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // Update inline allocation limit for old spaces.
5042b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  PagedSpaces spaces(this);
50433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (PagedSpace* space = spaces.next(); space != NULL;
5044b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org       space = spaces.next()) {
5045b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    space->EmptyAllocationInfo();
5046b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
5047b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
5048b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
5049b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
50507d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgV8_DECLARE_ONCE(initialize_gc_once);
50517d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
50527d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgstatic void InitializeGCOnce() {
50537d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  InitializeScavengingVisitorsTables();
50547d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  NewSpaceScavenger::Initialize();
50557d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  MarkCompactCollector::Initialize();
50567d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org}
50577d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
5058e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
505909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgbool Heap::SetUp() {
5060ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#ifdef DEBUG
5061394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  allocation_timeout_ = FLAG_gc_interval;
5062ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif
5063ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
506443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize heap spaces and initial maps and objects. Whenever something
506543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // goes wrong, just return false. The caller should check the results and
506643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // call Heap::TearDown() to release allocated memory.
506743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
50682efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // If the heap is not yet configured (e.g. through the API), configure it.
506943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Configuration is based on the flags new-space-size (really the semispace
507043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // size) and old-space-size if set or the initial values of semispace_size_
507143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // and old_generation_size_ otherwise.
5072ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!configured_) {
50737276f14ca716596e0a0d17539516370c1f453847kasper.lund    if (!ConfigureHeapDefault()) return false;
507443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
507543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50761e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  base::CallOnce(&initialize_gc_once, &InitializeGCOnce);
5077ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
5078d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  MarkMapPointersAsEncoded(false);
5079d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
5080f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up memory allocator.
5081f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!isolate_->memory_allocator()->SetUp(MaxReserved(), MaxExecutableSize()))
50823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    return false;
5083c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5084f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up new space.
50853c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (!new_space_.SetUp(reserved_semispace_size_, max_semi_space_size_)) {
50863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    return false;
50873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
5088fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  new_space_top_after_last_gc_ = new_space()->top();
508943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5090a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Initialize old pointer space.
50913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  old_pointer_space_ = new OldSpace(this, max_old_generation_size_,
50923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                    OLD_POINTER_SPACE, NOT_EXECUTABLE);
50939258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (old_pointer_space_ == NULL) return false;
5094f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!old_pointer_space_->SetUp()) return false;
5095a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
5096a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Initialize old data space.
50973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  old_data_space_ = new OldSpace(this, max_old_generation_size_, OLD_DATA_SPACE,
50983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                 NOT_EXECUTABLE);
50999258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (old_data_space_ == NULL) return false;
5100f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!old_data_space_->SetUp()) return false;
510143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51025b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  if (!isolate_->code_range()->SetUp(code_range_size_)) return false;
51035b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org
510443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize the code space, set its maximum capacity to the old
51057276f14ca716596e0a0d17539516370c1f453847kasper.lund  // generation size. It needs executable memory.
51069258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  code_space_ =
5107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      new OldSpace(this, max_old_generation_size_, CODE_SPACE, EXECUTABLE);
510843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (code_space_ == NULL) return false;
5109f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!code_space_->SetUp()) return false;
511043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
511143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Initialize map space.
511278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  map_space_ = new MapSpace(this, max_old_generation_size_, MAP_SPACE);
511343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (map_space_ == NULL) return false;
5114f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!map_space_->SetUp()) return false;
511543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
511641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Initialize simple cell space.
5117ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  cell_space_ = new CellSpace(this, max_old_generation_size_, CELL_SPACE);
5118defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  if (cell_space_ == NULL) return false;
5119f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!cell_space_->SetUp()) return false;
5120defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
512141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Initialize global property cell space.
512241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  property_cell_space_ = new PropertyCellSpace(this, max_old_generation_size_,
512341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                               PROPERTY_CELL_SPACE);
512441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (property_cell_space_ == NULL) return false;
512541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (!property_cell_space_->SetUp()) return false;
512641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
51279258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // The large object code space may contain code or data.  We set the memory
51289258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // to be non-executable here for safety, but this means we need to enable it
51299258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // explicitly when allocating large code objects.
5130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  lo_space_ = new LargeObjectSpace(this, max_old_generation_size_, LO_SPACE);
513143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (lo_space_ == NULL) return false;
5132f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!lo_space_->SetUp()) return false;
5133fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
5134f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up the seed that is used to randomize the string hash function.
5135e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(hash_seed() == 0);
5136f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (FLAG_randomize_hashes) {
5137f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    if (FLAG_hash_seed == 0) {
5138c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org      int rnd = isolate()->random_number_generator()->NextInt();
5139c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org      set_hash_seed(Smi::FromInt(rnd & Name::kHashBitMask));
5140fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    } else {
5141f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      set_hash_seed(Smi::FromInt(FLAG_hash_seed));
5142fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    }
5143fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  }
5144fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
5145ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
5146ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate_, IntPtrTEvent("heap-available", Available()));
514743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5148f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  store_buffer()->SetUp();
5149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
51506d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  mark_compact_collector()->SetUp();
51516d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org
515243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
515343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
515443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5155e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
515609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgbool Heap::CreateHeapObjects() {
515709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  // Create initial maps.
515809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (!CreateInitialMaps()) return false;
51593484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  CreateApiObjects();
516009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
516109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  // Create initial objects
51623484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  CreateInitialObjects();
51639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  CHECK_EQ(0, gc_count_);
516409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
51653c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  set_native_contexts_list(undefined_value());
51663c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  set_array_buffers_list(undefined_value());
51673c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  set_allocation_sites_list(undefined_value());
516825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  weak_object_to_code_table_ = undefined_value();
516909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  return true;
517009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org}
517109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
517243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5173c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Heap::SetStackLimits() {
5174e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(isolate_ != NULL);
5175e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(isolate_ == isolate());
517618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // On 64 bit machines, pointers are generally out of range of Smis.  We write
517718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // something that looks like an out of range Smi to the GC.
517818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
5179c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Set up the special root array entries containing the stack limits.
5180c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // These are actually addresses, but the tag makes the GC ignore it.
51813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  roots_[kStackLimitRootIndex] = reinterpret_cast<Object*>(
51823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      (isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag);
51833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  roots_[kRealStackLimitRootIndex] = reinterpret_cast<Object*>(
51843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag);
518518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
518618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
518718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
518843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::TearDown() {
5189c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
51901044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  if (FLAG_verify_heap) {
51911044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    Verify();
51921044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
51931044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org#endif
5194c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
5195057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  UpdateMaximumCommitted();
5196057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
51979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  if (FLAG_print_cumulative_gc_stat) {
5198e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org    PrintF("\n");
51999dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    PrintF("gc_count=%d ", gc_count_);
52009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    PrintF("mark_sweep_count=%d ", ms_count_);
5201c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("max_gc_pause=%.1f ", get_max_gc_pause());
5202c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("total_gc_time=%.1f ", total_gc_time_ms_);
5203c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    PrintF("min_in_mutator=%.1f ", get_min_in_mutator());
52043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", get_max_alive_after_gc());
52055c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    PrintF("total_marking_time=%.1f ", tracer_.cumulative_sweeping_duration());
52065c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    PrintF("total_sweeping_time=%.1f ", tracer_.cumulative_sweeping_duration());
52079dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    PrintF("\n\n");
52089dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
52099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
5210057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (FLAG_print_max_heap_committed) {
5211057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("\n");
5212057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_heap=%" V8_PTR_PREFIX "d ",
52133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           MaximumCommittedMemory());
5214057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_new_space=%" V8_PTR_PREFIX "d ",
52153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           new_space_.MaximumCommittedMemory());
5216057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_old_pointer_space=%" V8_PTR_PREFIX "d ",
52173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           old_data_space_->MaximumCommittedMemory());
5218057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_old_data_space=%" V8_PTR_PREFIX "d ",
52193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           old_pointer_space_->MaximumCommittedMemory());
5220057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_old_data_space=%" V8_PTR_PREFIX "d ",
52213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           old_pointer_space_->MaximumCommittedMemory());
5222057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_code_space=%" V8_PTR_PREFIX "d ",
52233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           code_space_->MaximumCommittedMemory());
5224057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_map_space=%" V8_PTR_PREFIX "d ",
52253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           map_space_->MaximumCommittedMemory());
5226057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_cell_space=%" V8_PTR_PREFIX "d ",
52273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           cell_space_->MaximumCommittedMemory());
5228057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_property_space=%" V8_PTR_PREFIX "d ",
52293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           property_cell_space_->MaximumCommittedMemory());
5230057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("maximum_committed_by_lo_space=%" V8_PTR_PREFIX "d ",
52313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           lo_space_->MaximumCommittedMemory());
5232057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    PrintF("\n\n");
5233057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  }
5234057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
52354b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  if (FLAG_verify_predictable) {
52364b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    PrintAlloctionsHash();
52374b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  }
52384b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
52391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  TearDownArrayBuffers();
52401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
5241ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->global_handles()->TearDown();
524243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5243ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  external_string_table_.TearDown();
524413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
5245d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  mark_compact_collector()->TearDown();
5246d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
52475a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  new_space_.TearDown();
524843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52499258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (old_pointer_space_ != NULL) {
52509258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    old_pointer_space_->TearDown();
52519258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    delete old_pointer_space_;
52529258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    old_pointer_space_ = NULL;
52539258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
52549258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
52559258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (old_data_space_ != NULL) {
52569258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    old_data_space_->TearDown();
52579258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    delete old_data_space_;
52589258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    old_data_space_ = NULL;
525943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
526043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
526143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (code_space_ != NULL) {
526243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    code_space_->TearDown();
526343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    delete code_space_;
526443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    code_space_ = NULL;
526543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
526643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
526743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (map_space_ != NULL) {
526843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    map_space_->TearDown();
526943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    delete map_space_;
527043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    map_space_ = NULL;
527143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
527243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5273defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  if (cell_space_ != NULL) {
5274defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    cell_space_->TearDown();
5275defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    delete cell_space_;
5276defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    cell_space_ = NULL;
5277defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  }
5278defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
527941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (property_cell_space_ != NULL) {
528041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    property_cell_space_->TearDown();
528141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    delete property_cell_space_;
528241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    property_cell_space_ = NULL;
528341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
528441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
528543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (lo_space_ != NULL) {
528643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    lo_space_->TearDown();
528743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    delete lo_space_;
528843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    lo_space_ = NULL;
528943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
529043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  store_buffer()->TearDown();
5292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  incremental_marking()->TearDown();
5293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5294ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->memory_allocator()->TearDown();
529543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
529643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
529743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5298528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid Heap::AddGCPrologueCallback(v8::Isolate::GCPrologueCallback callback,
52993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                 GCType gc_type, bool pass_isolate) {
5300e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(callback != NULL);
5301528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  GCPrologueCallbackPair pair(callback, gc_type, pass_isolate);
5302e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!gc_prologue_callbacks_.Contains(pair));
53035d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  return gc_prologue_callbacks_.Add(pair);
53045d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
53055d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
53065d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
5307528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid Heap::RemoveGCPrologueCallback(v8::Isolate::GCPrologueCallback callback) {
5308e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(callback != NULL);
53095d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
53105d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    if (gc_prologue_callbacks_[i].callback == callback) {
53115d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      gc_prologue_callbacks_.Remove(i);
53125d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return;
53135d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    }
53145d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
53155d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  UNREACHABLE();
53165d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
53175d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
53185d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
5319528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid Heap::AddGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback,
53203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                 GCType gc_type, bool pass_isolate) {
5321e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(callback != NULL);
5322528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  GCEpilogueCallbackPair pair(callback, gc_type, pass_isolate);
5323e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!gc_epilogue_callbacks_.Contains(pair));
53245d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  return gc_epilogue_callbacks_.Add(pair);
53255d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
53265d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
53275d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
5328528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid Heap::RemoveGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback) {
5329e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(callback != NULL);
53305d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
53315d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    if (gc_epilogue_callbacks_[i].callback == callback) {
53325d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      gc_epilogue_callbacks_.Remove(i);
53335d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return;
53345d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    }
53355d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
53365d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  UNREACHABLE();
53375d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
53385d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
53395d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
5340865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org// TODO(ishell): Find a better place for this.
5341865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgvoid Heap::AddWeakObjectToCodeDependency(Handle<Object> obj,
5342865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                                         Handle<DependentCode> dep) {
5343e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!InNewSpace(*obj));
5344e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!InNewSpace(*dep));
5345aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org  // This handle scope keeps the table handle local to this function, which
5346aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org  // allows us to safely skip write barriers in table update operations.
5347865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  HandleScope scope(isolate());
5348865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<WeakHashTable> table(WeakHashTable::cast(weak_object_to_code_table_),
5349865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                              isolate());
5350865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  table = WeakHashTable::Put(table, obj, dep);
5351865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org
5352865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  if (ShouldZapGarbage() && weak_object_to_code_table_ != *table) {
5353dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    WeakHashTable::cast(weak_object_to_code_table_)->Zap(the_hole_value());
5354dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  }
5355865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  set_weak_object_to_code_table(*table);
5356e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(*dep, table->Lookup(obj));
535725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org}
535825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
535925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
53603484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgDependentCode* Heap::LookupWeakObjectToCodeDependency(Handle<Object> obj) {
536125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  Object* dep = WeakHashTable::cast(weak_object_to_code_table_)->Lookup(obj);
536225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  if (dep->IsDependentCode()) return DependentCode::cast(dep);
536325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  return DependentCode::cast(empty_fixed_array());
536425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org}
536525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
536625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
536725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.orgvoid Heap::EnsureWeakObjectToCodeTable() {
536825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  if (!weak_object_to_code_table()->IsHashTable()) {
53693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    set_weak_object_to_code_table(
53703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        *WeakHashTable::New(isolate(), 16, USE_DEFAULT_MINIMUM_CAPACITY,
53713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                            TENURED));
537225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
537325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org}
537425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
537525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
53765c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.orgvoid Heap::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
53775c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  v8::internal::V8::FatalProcessOutOfMemory(location, take_snapshot);
53785c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org}
53795c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
538043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
538143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
53823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass PrintHandleVisitor : public ObjectVisitor {
538343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
538443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void VisitPointers(Object** start, Object** end) {
538543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (Object** p = start; p < end; p++)
53863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      PrintF("  handle %p to %p\n", reinterpret_cast<void*>(p),
5387f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org             reinterpret_cast<void*>(*p));
538843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
538943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
539043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5391e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
539243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::PrintHandles() {
539343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("Handles:\n");
539443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintHandleVisitor v;
5395ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->handle_scope_implementer()->Iterate(&v);
539643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
539743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
539843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
539943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
540043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54019258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgSpace* AllSpaces::next() {
54029258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  switch (counter_++) {
54039258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case NEW_SPACE:
54047c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->new_space();
54059258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
54067c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_pointer_space();
54079258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
54087c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_data_space();
54099258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case CODE_SPACE:
54107c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->code_space();
54119258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case MAP_SPACE:
54127c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->map_space();
5413defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    case CELL_SPACE:
54147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->cell_space();
541541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_SPACE:
541641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      return heap_->property_cell_space();
54179258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case LO_SPACE:
54187c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->lo_space();
54199258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    default:
54209258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return NULL;
54219258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
54229258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
54239258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
54249258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
54259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgPagedSpace* PagedSpaces::next() {
54269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  switch (counter_++) {
54279258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
54287c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_pointer_space();
54299258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
54307c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_data_space();
54319258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case CODE_SPACE:
54327c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->code_space();
54339258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case MAP_SPACE:
54347c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->map_space();
5435defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    case CELL_SPACE:
54367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->cell_space();
543741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_SPACE:
543841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      return heap_->property_cell_space();
54399258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    default:
54409258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return NULL;
54419258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
54429258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
54439258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
54449258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
54459258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.orgOldSpace* OldSpaces::next() {
54469258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  switch (counter_++) {
54479258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
54487c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_pointer_space();
54499258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
54507c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->old_data_space();
54519258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case CODE_SPACE:
54527c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return heap_->code_space();
54539258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    default:
54549258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      return NULL;
54559258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
54569258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
54579258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
54589258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
54597c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgSpaceIterator::SpaceIterator(Heap* heap)
54607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    : heap_(heap),
54617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      current_space_(FIRST_SPACE),
54624a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      iterator_(NULL),
54633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      size_func_(NULL) {}
54644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
54654a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
54667c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgSpaceIterator::SpaceIterator(Heap* heap, HeapObjectCallback size_func)
54677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    : heap_(heap),
54687c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      current_space_(FIRST_SPACE),
54694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      iterator_(NULL),
54703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      size_func_(size_func) {}
54717276f14ca716596e0a0d17539516370c1f453847kasper.lund
54727276f14ca716596e0a0d17539516370c1f453847kasper.lund
54737276f14ca716596e0a0d17539516370c1f453847kasper.lundSpaceIterator::~SpaceIterator() {
54747276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Delete active iterator if any.
54757276f14ca716596e0a0d17539516370c1f453847kasper.lund  delete iterator_;
54767276f14ca716596e0a0d17539516370c1f453847kasper.lund}
54777276f14ca716596e0a0d17539516370c1f453847kasper.lund
54787276f14ca716596e0a0d17539516370c1f453847kasper.lund
54797276f14ca716596e0a0d17539516370c1f453847kasper.lundbool SpaceIterator::has_next() {
54807276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Iterate until no more spaces.
54817276f14ca716596e0a0d17539516370c1f453847kasper.lund  return current_space_ != LAST_SPACE;
54827276f14ca716596e0a0d17539516370c1f453847kasper.lund}
54837276f14ca716596e0a0d17539516370c1f453847kasper.lund
54847276f14ca716596e0a0d17539516370c1f453847kasper.lund
54857276f14ca716596e0a0d17539516370c1f453847kasper.lundObjectIterator* SpaceIterator::next() {
54867276f14ca716596e0a0d17539516370c1f453847kasper.lund  if (iterator_ != NULL) {
54877276f14ca716596e0a0d17539516370c1f453847kasper.lund    delete iterator_;
54887276f14ca716596e0a0d17539516370c1f453847kasper.lund    iterator_ = NULL;
54897276f14ca716596e0a0d17539516370c1f453847kasper.lund    // Move to the next space
54907276f14ca716596e0a0d17539516370c1f453847kasper.lund    current_space_++;
54917276f14ca716596e0a0d17539516370c1f453847kasper.lund    if (current_space_ > LAST_SPACE) {
54927276f14ca716596e0a0d17539516370c1f453847kasper.lund      return NULL;
54937276f14ca716596e0a0d17539516370c1f453847kasper.lund    }
54947276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
54957276f14ca716596e0a0d17539516370c1f453847kasper.lund
54967276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Return iterator for the new current space.
54977276f14ca716596e0a0d17539516370c1f453847kasper.lund  return CreateIterator();
54987276f14ca716596e0a0d17539516370c1f453847kasper.lund}
54997276f14ca716596e0a0d17539516370c1f453847kasper.lund
55007276f14ca716596e0a0d17539516370c1f453847kasper.lund
55017276f14ca716596e0a0d17539516370c1f453847kasper.lund// Create an iterator for the space to iterate.
55027276f14ca716596e0a0d17539516370c1f453847kasper.lundObjectIterator* SpaceIterator::CreateIterator() {
5503e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(iterator_ == NULL);
55047276f14ca716596e0a0d17539516370c1f453847kasper.lund
55057276f14ca716596e0a0d17539516370c1f453847kasper.lund  switch (current_space_) {
55067276f14ca716596e0a0d17539516370c1f453847kasper.lund    case NEW_SPACE:
55077c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new SemiSpaceIterator(heap_->new_space(), size_func_);
55087276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
55099258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_POINTER_SPACE:
55107c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ =
55117c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org          new HeapObjectIterator(heap_->old_pointer_space(), size_func_);
55129258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org      break;
55139258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    case OLD_DATA_SPACE:
55147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new HeapObjectIterator(heap_->old_data_space(), size_func_);
55157276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
55167276f14ca716596e0a0d17539516370c1f453847kasper.lund    case CODE_SPACE:
55177c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new HeapObjectIterator(heap_->code_space(), size_func_);
55187276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
55197276f14ca716596e0a0d17539516370c1f453847kasper.lund    case MAP_SPACE:
55207c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new HeapObjectIterator(heap_->map_space(), size_func_);
55217276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
5522defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    case CELL_SPACE:
55237c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new HeapObjectIterator(heap_->cell_space(), size_func_);
5524defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      break;
552541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_SPACE:
55263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      iterator_ =
55273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          new HeapObjectIterator(heap_->property_cell_space(), size_func_);
552841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      break;
55297276f14ca716596e0a0d17539516370c1f453847kasper.lund    case LO_SPACE:
55307c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      iterator_ = new LargeObjectIterator(heap_->lo_space(), size_func_);
55317276f14ca716596e0a0d17539516370c1f453847kasper.lund      break;
55327276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
55337276f14ca716596e0a0d17539516370c1f453847kasper.lund
55347276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Return the newly allocated iterator;
5535e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(iterator_ != NULL);
55367276f14ca716596e0a0d17539516370c1f453847kasper.lund  return iterator_;
55377276f14ca716596e0a0d17539516370c1f453847kasper.lund}
55387276f14ca716596e0a0d17539516370c1f453847kasper.lund
55397276f14ca716596e0a0d17539516370c1f453847kasper.lund
5540023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgclass HeapObjectsFilter {
5541023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org public:
5542023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  virtual ~HeapObjectsFilter() {}
5543023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  virtual bool SkipObject(HeapObject* object) = 0;
5544023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org};
5545023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
5546023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
5547023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgclass UnreachableObjectsFilter : public HeapObjectsFilter {
5548023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org public:
55493d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) {
5550394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MarkReachableObjects();
5551394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
5552394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
5553394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ~UnreachableObjectsFilter() {
55543d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    heap_->mark_compact_collector()->ClearMarkbits();
5555023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  }
5556023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
5557023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  bool SkipObject(HeapObject* object) {
5558394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(object);
5559394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return !mark_bit.Get();
5560023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  }
5561023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
5562023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org private:
5563394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  class MarkingVisitor : public ObjectVisitor {
5564023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org   public:
5565394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MarkingVisitor() : marking_stack_(10) {}
5566023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
5567023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    void VisitPointers(Object** start, Object** end) {
5568023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      for (Object** p = start; p < end; p++) {
5569023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org        if (!(*p)->IsHeapObject()) continue;
5570023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org        HeapObject* obj = HeapObject::cast(*p);
5571394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        MarkBit mark_bit = Marking::MarkBitFrom(obj);
5572394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        if (!mark_bit.Get()) {
5573394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          mark_bit.Set();
5574394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          marking_stack_.Add(obj);
5575023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org        }
5576023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      }
5577023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    }
5578023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
5579394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    void TransitiveClosure() {
5580394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      while (!marking_stack_.is_empty()) {
5581394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        HeapObject* obj = marking_stack_.RemoveLast();
5582394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        obj->Iterate(this);
5583394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
5584023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    }
5585023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
5586023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org   private:
5587394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    List<HeapObject*> marking_stack_;
5588023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  };
5589023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
5590394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  void MarkReachableObjects() {
5591394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MarkingVisitor visitor;
55923d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    heap_->IterateRoots(&visitor, VISIT_ALL);
5593394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    visitor.TransitiveClosure();
5594023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  }
5595023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
55963d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Heap* heap_;
559779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation_;
5598023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org};
5599023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
5600023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
56017c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgHeapIterator::HeapIterator(Heap* heap)
5602fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    : make_heap_iterable_helper_(heap),
5603fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      no_heap_allocation_(),
5604fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      heap_(heap),
56057c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      filtering_(HeapIterator::kNoFiltering),
56064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      filter_(NULL) {
56074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  Init();
56084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
56094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
56104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
56117c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgHeapIterator::HeapIterator(Heap* heap,
56127c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                           HeapIterator::HeapObjectsFiltering filtering)
5613fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    : make_heap_iterable_helper_(heap),
5614fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      no_heap_allocation_(),
5615fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      heap_(heap),
56167c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      filtering_(filtering),
56174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com      filter_(NULL) {
561843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Init();
561943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
562043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
562143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgHeapIterator::~HeapIterator() { Shutdown(); }
562343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
562443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
562543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid HeapIterator::Init() {
562643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Start the iteration.
56277c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  space_iterator_ = new SpaceIterator(heap_);
5628023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  switch (filtering_) {
5629023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    case kFilterUnreachable:
56303d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      filter_ = new UnreachableObjectsFilter(heap_);
5631023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      break;
5632023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    default:
5633023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      break;
56344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
563543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  object_iterator_ = space_iterator_->next();
563643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
563743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
563843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
563943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid HeapIterator::Shutdown() {
56404a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#ifdef DEBUG
5641023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  // Assert that in filtering mode we have iterated through all
56424a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // objects. Otherwise, heap will be left in an inconsistent state.
5643023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  if (filtering_ != kNoFiltering) {
5644e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(object_iterator_ == NULL);
56454a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
56464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#endif
564743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure the last iterator is deallocated.
564843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  delete space_iterator_;
564943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  space_iterator_ = NULL;
565043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  object_iterator_ = NULL;
56514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  delete filter_;
56524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  filter_ = NULL;
565343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
565443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
565543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5656b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgHeapObject* HeapIterator::next() {
56574a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  if (filter_ == NULL) return NextObject();
56584a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
56594a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  HeapObject* obj = NextObject();
5660023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  while (obj != NULL && filter_->SkipObject(obj)) obj = NextObject();
56614a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return obj;
56624a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
56634a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
56644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
56654a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comHeapObject* HeapIterator::NextObject() {
566643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // No iterator means we are done.
5667b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (object_iterator_ == NULL) return NULL;
566843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5669b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (HeapObject* obj = object_iterator_->next_object()) {
567043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If the current iterator has more objects we are fine.
5671b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return obj;
567243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
567343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Go though the spaces looking for one that has objects.
567443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (space_iterator_->has_next()) {
567543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      object_iterator_ = space_iterator_->next();
5676b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      if (HeapObject* obj = object_iterator_->next_object()) {
5677b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org        return obj;
567843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
567943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
568043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
568143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Done with the last space.
568243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  object_iterator_ = NULL;
5683b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return NULL;
568443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
568543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
568643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
568743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid HeapIterator::reset() {
568843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Restart the iterator.
568943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Shutdown();
569043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Init();
569143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
569243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
569343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
569446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org#ifdef DEBUG
56953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
5696ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgObject* const PathTracer::kAnyGlobalObject = NULL;
569743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass PathTracer::MarkVisitor : public ObjectVisitor {
56993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public:
57003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  explicit MarkVisitor(PathTracer* tracer) : tracer_(tracer) {}
57013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void VisitPointers(Object** start, Object** end) {
57023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Scan all HeapObject pointers in [start, end)
57033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    for (Object** p = start; !tracer_->found() && (p < end); p++) {
57043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      if ((*p)->IsHeapObject()) tracer_->MarkRecursively(p, this);
57053a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
57063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
570743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private:
57093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  PathTracer* tracer_;
57103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org};
571143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
571243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass PathTracer::UnmarkVisitor : public ObjectVisitor {
571443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
57153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  explicit UnmarkVisitor(PathTracer* tracer) : tracer_(tracer) {}
571643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void VisitPointers(Object** start, Object** end) {
57173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Scan all HeapObject pointers in [start, end)
571843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (Object** p = start; p < end; p++) {
57193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      if ((*p)->IsHeapObject()) tracer_->UnmarkRecursively(p, this);
572043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
572143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
57223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
57233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private:
57243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  PathTracer* tracer_;
572543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
572643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
572743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::VisitPointers(Object** start, Object** end) {
57293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  bool done = ((what_to_find_ == FIND_FIRST) && found_target_);
57303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Visit all HeapObject pointers in [start, end)
57313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  for (Object** p = start; !done && (p < end); p++) {
57323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if ((*p)->IsHeapObject()) {
57333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      TracePathFrom(p);
57343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      done = ((what_to_find_ == FIND_FIRST) && found_target_);
57353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
57363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
57373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
57383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
57393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
57403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::Reset() {
57413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  found_target_ = false;
57423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  object_stack_.Clear();
57433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
57443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
57453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
57463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::TracePathFrom(Object** root) {
5747e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((search_target_ == kAnyGlobalObject) ||
57483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org         search_target_->IsHeapObject());
57493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  found_target_in_trace_ = false;
57505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Reset();
57513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
57523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  MarkVisitor mark_visitor(this);
57533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  MarkRecursively(root, &mark_visitor);
57543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
57553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  UnmarkVisitor unmark_visitor(this);
57563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  UnmarkRecursively(root, &unmark_visitor);
57573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
57583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ProcessResults();
57593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
57603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
57613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
576246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgstatic bool SafeIsNativeContext(HeapObject* obj) {
576346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return obj->map() == obj->GetHeap()->raw_unchecked_native_context_map();
5764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
5765c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
57673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) {
576843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!(*p)->IsHeapObject()) return;
576943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
577043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapObject* obj = HeapObject::cast(*p);
577143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5772196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  MapWord map_word = obj->map_word();
5773196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (!map_word.ToMap()->IsHeapObject()) return;  // visited before
577443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if (found_target_in_trace_) return;  // stop if target found
57763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  object_stack_.Add(obj);
57773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if (((search_target_ == kAnyGlobalObject) && obj->IsJSGlobalObject()) ||
57783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      (obj == search_target_)) {
57793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    found_target_in_trace_ = true;
57803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    found_target_ = true;
578143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
578243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
578343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
578446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  bool is_native_context = SafeIsNativeContext(obj);
57853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
578643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // not visited yet
5787196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Map* map = Map::cast(map_word.ToMap());
578843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5789196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  MapWord marked_map_word =
5790196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      MapWord::FromRawValue(obj->map_word().ToRawValue() + kMarkTag);
5791196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  obj->set_map_word(marked_map_word);
579243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Scan the object body.
579446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (is_native_context && (visit_mode_ == VISIT_ONLY_STRONG)) {
57953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // This is specialized to scan Context's properly.
57963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Object** start =
57973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        reinterpret_cast<Object**>(obj->address() + Context::kHeaderSize);
57983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Object** end =
57993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        reinterpret_cast<Object**>(obj->address() + Context::kHeaderSize +
58003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   Context::FIRST_WEAK_SLOT * kPointerSize);
58012ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    mark_visitor->VisitPointers(start, end);
58023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
5803196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    obj->IterateBody(map->instance_type(), obj->SizeFromMap(map), mark_visitor);
58043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
580543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Scan the map after the body because the body is a lot more interesting
58073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // when doing leak detection.
5808196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  MarkRecursively(reinterpret_cast<Object**>(&map), mark_visitor);
580943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5810196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (!found_target_in_trace_) {  // don't pop if found the target
58113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    object_stack_.RemoveLast();
5812196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
581343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
581443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
581543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::UnmarkRecursively(Object** p, UnmarkVisitor* unmark_visitor) {
581743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!(*p)->IsHeapObject()) return;
581843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
581943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapObject* obj = HeapObject::cast(*p);
582043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5821196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  MapWord map_word = obj->map_word();
5822196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (map_word.ToMap()->IsHeapObject()) return;  // unmarked already
582343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5824196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  MapWord unmarked_map_word =
5825196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      MapWord::FromRawValue(map_word.ToRawValue() - kMarkTag);
5826196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  obj->set_map_word(unmarked_map_word);
582743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5828196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Map* map = Map::cast(unmarked_map_word.ToMap());
582943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5830196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  UnmarkRecursively(reinterpret_cast<Object**>(&map), unmark_visitor);
583143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5832196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  obj->IterateBody(map->instance_type(), obj->SizeFromMap(map), unmark_visitor);
583343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
583443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
583543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid PathTracer::ProcessResults() {
58373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if (found_target_) {
5838f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    OFStream os(stdout);
5839f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "=====================================\n"
5840f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org       << "====        Path to object       ====\n"
5841f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org       << "=====================================\n\n";
584243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5843e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!object_stack_.is_empty());
58443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    for (int i = 0; i < object_stack_.length(); i++) {
5845f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      if (i > 0) os << "\n     |\n     |\n     V\n\n";
5846f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      object_stack_[i]->Print(os);
584743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
5848f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "=====================================\n";
584943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
585043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
585143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
585243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5853ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org// Triggers a depth-first traversal of reachable objects from one
5854ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org// given root object and finds a path to a specific heap object and
5855ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org// prints it.
5856ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.orgvoid Heap::TracePathToObjectFrom(Object* target, Object* root) {
5857ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL);
5858ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  tracer.VisitPointer(&root);
5859ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org}
5860ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
5861ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
586243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Triggers a depth-first traversal of reachable objects from roots
586343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and finds a path to a specific heap object and prints it.
586413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Heap::TracePathToObject(Object* target) {
58653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL);
58663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  IterateRoots(&tracer, VISIT_ONLY_STRONG);
586743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
586843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
586943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
587043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Triggers a depth-first traversal of reachable objects from roots
587143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and finds a path to any global object and prints it. Useful for
587243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// determining the source for leaks of global objects.
587343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Heap::TracePathToGlobal() {
58743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  PathTracer tracer(PathTracer::kAnyGlobalObject, PathTracer::FIND_ALL,
58753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                    VISIT_ALL);
58763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  IterateRoots(&tracer, VISIT_ONLY_STRONG);
587743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
587843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
587943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
588043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5881f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.orgvoid Heap::UpdateCumulativeGCStatistics(double duration,
5882f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                                        double spent_in_mutator,
5883f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                                        double marking_time) {
588493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  if (FLAG_print_cumulative_gc_stat) {
588593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    total_gc_time_ms_ += duration;
588693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    max_gc_pause_ = Max(max_gc_pause_, duration);
5887f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org    max_alive_after_gc_ = Max(max_alive_after_gc_, SizeOfObjects());
5888474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    min_in_mutator_ = Min(min_in_mutator_, spent_in_mutator);
588993720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  } else if (FLAG_trace_gc_verbose) {
589093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    total_gc_time_ms_ += duration;
589193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  }
589293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org
589393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  marking_time_ += marking_time;
589493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org}
589593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org
589693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org
5897a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgint KeyedLookupCache::Hash(Handle<Map> map, Handle<Name> name) {
5898a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  DisallowHeapAllocation no_gc;
58995aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Uses only lower 32 bits if pointers are larger.
59005aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  uintptr_t addr_hash =
5901a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      static_cast<uint32_t>(reinterpret_cast<uintptr_t>(*map)) >> kMapHashShift;
5902b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask);
59035aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
59045aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
59055aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
5906a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgint KeyedLookupCache::Lookup(Handle<Map> map, Handle<Name> name) {
5907a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  DisallowHeapAllocation no_gc;
590805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  int index = (Hash(map, name) & kHashMask);
5909659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  for (int i = 0; i < kEntriesPerBucket; i++) {
5910659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Key& key = keys_[index + i];
5911a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if ((key.map == *map) && key.name->Equals(*name)) {
5912659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      return field_offsets_[index + i];
5913659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
591405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
5915ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return kNotFound;
59165aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
59175aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
59185aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
59193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid KeyedLookupCache::Update(Handle<Map> map, Handle<Name> name,
5920a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                              int field_offset) {
5921a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  DisallowHeapAllocation no_gc;
5922750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (!name->IsUniqueName()) {
59233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (!StringTable::InternalizeStringIfExists(
59243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org             name->GetIsolate(), Handle<String>::cast(name)).ToHandle(&name)) {
5925750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      return;
5926659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
5927750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
5928f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // This cache is cleared only between mark compact passes, so we expect the
5929f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // cache to only contain old space names.
5930e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!map->GetIsolate()->heap()->InNewSpace(*name));
5931659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
5932750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  int index = (Hash(map, name) & kHashMask);
5933750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // After a GC there will be free slots, so we use them in order (this may
5934750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // help to get the most frequently used one in position 0).
59353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (int i = 0; i < kEntriesPerBucket; i++) {
5936659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Key& key = keys_[index];
5937750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Object* free_entry_indicator = NULL;
5938750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (key.map == free_entry_indicator) {
5939a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      key.map = *map;
5940a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      key.name = *name;
5941750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      field_offsets_[index + i] = field_offset;
5942750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      return;
5943750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
59445aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
5945750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // No free entry found in this bucket, so we move them all down one and
5946750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // put the new entry at position zero.
5947750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  for (int i = kEntriesPerBucket - 1; i > 0; i--) {
5948750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Key& key = keys_[index + i];
5949750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Key& key2 = keys_[index + i - 1];
5950750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    key = key2;
5951750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    field_offsets_[index + i] = field_offsets_[index + i - 1];
5952750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
5953750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
5954750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Write the new first entry.
5955750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Key& key = keys_[index];
5956a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  key.map = *map;
5957a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  key.name = *name;
5958750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  field_offsets_[index] = field_offset;
59595aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
59605aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
59615aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
59625aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid KeyedLookupCache::Clear() {
59635aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  for (int index = 0; index < kLength; index++) keys_[index].map = NULL;
59645aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
59655aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
59665aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
59675aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid DescriptorLookupCache::Clear() {
596806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  for (int index = 0; index < kLength; index++) keys_[index].source = NULL;
59695aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
59705aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
59715aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
597213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid ExternalStringTable::CleanUp() {
597313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  int last = 0;
597413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  for (int i = 0; i < new_space_strings_.length(); ++i) {
597572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (new_space_strings_[i] == heap_->the_hole_value()) {
5976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      continue;
5977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
5978e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(new_space_strings_[i]->IsExternalString());
5979ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (heap_->InNewSpace(new_space_strings_[i])) {
598013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      new_space_strings_[last++] = new_space_strings_[i];
598113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    } else {
598213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      old_space_strings_.Add(new_space_strings_[i]);
598313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    }
598413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
598513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  new_space_strings_.Rewind(last);
598646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  new_space_strings_.Trim();
598746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
598813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  last = 0;
598913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  for (int i = 0; i < old_space_strings_.length(); ++i) {
599072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (old_space_strings_[i] == heap_->the_hole_value()) {
5991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      continue;
5992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
5993e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(old_space_strings_[i]->IsExternalString());
5994e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!heap_->InNewSpace(old_space_strings_[i]));
599513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    old_space_strings_[last++] = old_space_strings_[i];
599613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
599713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  old_space_strings_.Rewind(last);
599846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  old_space_strings_.Trim();
5999c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
6000394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
6001394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Verify();
6002394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
6003c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif
600413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
600513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
600613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
600713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid ExternalStringTable::TearDown() {
6008f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  for (int i = 0; i < new_space_strings_.length(); ++i) {
6009f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i]));
6010f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
601113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  new_space_strings_.Free();
6012f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  for (int i = 0; i < old_space_strings_.length(); ++i) {
6013f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i]));
6014f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
601513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  old_space_strings_.Free();
601613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
601713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
601813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
6019c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) {
6020c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  chunk->set_next_chunk(chunks_queued_for_free_);
6021c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  chunks_queued_for_free_ = chunk;
6022c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
6023c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6024c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid Heap::FreeQueuedChunks() {
6026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (chunks_queued_for_free_ == NULL) return;
6027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MemoryChunk* next;
6028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MemoryChunk* chunk;
6029c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) {
6030c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    next = chunk->next_chunk();
6031c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    chunk->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED);
6032c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6033c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (chunk->owner()->identity() == LO_SPACE) {
6034c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // StoreBuffer::Filter relies on MemoryChunk::FromAnyPointerAddress.
6035c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // If FromAnyPointerAddress encounters a slot that belongs to a large
6036c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // chunk queued for deletion it will fail to find the chunk because
6037c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // it try to perform a search in the list of pages owned by of the large
6038c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // object space and queued chunks were detached from that list.
6039c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // To work around this we split large chunk into normal kPageSize aligned
60402c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org      // pieces and initialize size, owner and flags field of every piece.
60412c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org      // If FromAnyPointerAddress encounters a slot that belongs to one of
6042c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // these smaller pieces it will treat it as a slot on a normal Page.
60439a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org      Address chunk_end = chunk->address() + chunk->size();
60443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      MemoryChunk* inner =
60453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          MemoryChunk::FromAddress(chunk->address() + Page::kPageSize);
60469a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org      MemoryChunk* inner_last = MemoryChunk::FromAddress(chunk_end - 1);
6047c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      while (inner <= inner_last) {
6048c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Size of a large chunk is always a multiple of
604904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org        // OS::AllocateAlignment() so there is always
6050c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // enough space for a fake MemoryChunk header.
60519a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org        Address area_end = Min(inner->address() + Page::kPageSize, chunk_end);
60529a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org        // Guard against overflow.
60539a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org        if (area_end < inner->address()) area_end = chunk_end;
60549a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org        inner->SetArea(inner->address(), area_end);
60552c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org        inner->set_size(Page::kPageSize);
6056c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        inner->set_owner(lo_space());
6057c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        inner->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED);
60583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        inner = MemoryChunk::FromAddress(inner->address() + Page::kPageSize);
6059c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
6060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
6061c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
6062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  isolate_->heap()->store_buffer()->Compact();
6063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED);
6064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) {
6065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    next = chunk->next_chunk();
6066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    isolate_->memory_allocator()->Free(chunk);
6067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
6068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  chunks_queued_for_free_ = NULL;
6069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
6070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
60712c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
60722c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgvoid Heap::RememberUnmappedPage(Address page, bool compacted) {
60732c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  uintptr_t p = reinterpret_cast<uintptr_t>(page);
60742c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  // Tag the page pointer to make it findable in the dump file.
60752c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  if (compacted) {
60762c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    p ^= 0xc1ead & (Page::kPageSize - 1);  // Cleared.
60772c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  } else {
60782c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    p ^= 0x1d1ed & (Page::kPageSize - 1);  // I died.
60792c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  }
60802c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  remembered_unmapped_pages_[remembered_unmapped_pages_index_] =
60812c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      reinterpret_cast<Address>(p);
60822c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  remembered_unmapped_pages_index_++;
60832c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  remembered_unmapped_pages_index_ %= kRememberedUnmappedPages;
60842c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org}
60852c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
608628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
608728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid Heap::ClearObjectStats(bool clear_last_time_stats) {
608828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  memset(object_counts_, 0, sizeof(object_counts_));
608928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  memset(object_sizes_, 0, sizeof(object_sizes_));
609028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  if (clear_last_time_stats) {
609128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    memset(object_counts_last_time_, 0, sizeof(object_counts_last_time_));
609228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    memset(object_sizes_last_time_, 0, sizeof(object_sizes_last_time_));
609328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  }
609428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org}
609528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
609628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
60975de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgstatic base::LazyMutex checkpoint_object_stats_mutex = LAZY_MUTEX_INITIALIZER;
609828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
609928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
610028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid Heap::CheckpointObjectStats() {
61015de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::LockGuard<base::Mutex> lock_guard(
61025de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org      checkpoint_object_stats_mutex.Pointer());
610328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  Counters* counters = isolate()->counters();
61043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define ADJUST_LAST_TIME_OBJECT_COUNT(name)              \
61053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  counters->count_of_##name()->Increment(                \
61063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      static_cast<int>(object_counts_[name]));           \
61073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  counters->count_of_##name()->Decrement(                \
61083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      static_cast<int>(object_counts_last_time_[name])); \
61093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  counters->size_of_##name()->Increment(                 \
61103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      static_cast<int>(object_sizes_[name]));            \
61113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  counters->size_of_##name()->Decrement(                 \
611228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      static_cast<int>(object_sizes_last_time_[name]));
611328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
611428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org#undef ADJUST_LAST_TIME_OBJECT_COUNT
6115753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  int index;
6116753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#define ADJUST_LAST_TIME_OBJECT_COUNT(name)               \
6117753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  index = FIRST_CODE_KIND_SUB_TYPE + Code::name;          \
6118753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  counters->count_of_CODE_TYPE_##name()->Increment(       \
6119753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(object_counts_[index]));           \
6120753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  counters->count_of_CODE_TYPE_##name()->Decrement(       \
6121753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(object_counts_last_time_[index])); \
6122753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  counters->size_of_CODE_TYPE_##name()->Increment(        \
6123753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(object_sizes_[index]));            \
6124753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  counters->size_of_CODE_TYPE_##name()->Decrement(        \
6125753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      static_cast<int>(object_sizes_last_time_[index]));
6126753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  CODE_KIND_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
6127753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#undef ADJUST_LAST_TIME_OBJECT_COUNT
6128304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#define ADJUST_LAST_TIME_OBJECT_COUNT(name)               \
6129304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  index = FIRST_FIXED_ARRAY_SUB_TYPE + name;              \
6130304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  counters->count_of_FIXED_ARRAY_##name()->Increment(     \
6131304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      static_cast<int>(object_counts_[index]));           \
6132304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  counters->count_of_FIXED_ARRAY_##name()->Decrement(     \
6133304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      static_cast<int>(object_counts_last_time_[index])); \
6134304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  counters->size_of_FIXED_ARRAY_##name()->Increment(      \
6135304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      static_cast<int>(object_sizes_[index]));            \
6136304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  counters->size_of_FIXED_ARRAY_##name()->Decrement(      \
6137304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      static_cast<int>(object_sizes_last_time_[index]));
6138304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
6139304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#undef ADJUST_LAST_TIME_OBJECT_COUNT
6140057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org#define ADJUST_LAST_TIME_OBJECT_COUNT(name)                                   \
6141057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  index =                                                                     \
6142057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge; \
6143057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  counters->count_of_CODE_AGE_##name()->Increment(                            \
6144057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      static_cast<int>(object_counts_[index]));                               \
6145057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  counters->count_of_CODE_AGE_##name()->Decrement(                            \
6146057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      static_cast<int>(object_counts_last_time_[index]));                     \
6147057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  counters->size_of_CODE_AGE_##name()->Increment(                             \
6148057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      static_cast<int>(object_sizes_[index]));                                \
6149057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  counters->size_of_CODE_AGE_##name()->Decrement(                             \
6150e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org      static_cast<int>(object_sizes_last_time_[index]));
6151057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6152e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org#undef ADJUST_LAST_TIME_OBJECT_COUNT
6153753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6154d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6155d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
615628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  ClearObjectStats();
615728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org}
61583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
61593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}  // namespace v8::internal
6160