13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_HEAP_INL_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_HEAP_INL_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "heap.h"
3244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "isolate.h"
33257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "list-inl.h"
34257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "objects.h"
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "platform.h"
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8-counters.h"
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "store-buffer.h"
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "store-buffer-inl.h"
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid PromotionQueue::insert(HeapObject* target, int size) {
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (emergency_stack_ != NULL) {
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    emergency_stack_->Add(Entry(target, size));
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return;
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (NewSpacePage::IsAtStart(reinterpret_cast<Address>(rear_))) {
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    NewSpacePage* rear_page =
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        NewSpacePage::FromAddress(reinterpret_cast<Address>(rear_));
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(!rear_page->prev_page()->is_anchor());
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    rear_ = reinterpret_cast<intptr_t*>(rear_page->prev_page()->area_end());
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ActivateGuardIfOnTheSamePage();
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (guard_) {
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(GetHeadPage() ==
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch           Page::FromAllocationTop(reinterpret_cast<Address>(limit_)));
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if ((rear_ - 2) < limit_) {
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RelocateQueueHead();
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      emergency_stack_->Add(Entry(target, size));
643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return;
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  *(--rear_) = reinterpret_cast<intptr_t>(target);
6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  *(--rear_) = size;
7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Assert no overflow into live objects.
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SemiSpace::AssertValidRange(HEAP->new_space()->top(),
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              reinterpret_cast<Address>(rear_));
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PromotionQueue::ActivateGuardIfOnTheSamePage() {
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  guard_ = guard_ ||
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap_->new_space()->active_space()->current_page()->address() ==
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      GetHeadPage()->address();
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
859fac840a46e8b7e26894f4792ba26dde14c56b04Steve BlockMaybeObject* Heap::AllocateStringFromUtf8(Vector<const char> str,
869fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                                          PretenureFlag pretenure) {
879fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Check for ASCII first since this is the common case.
889fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  if (String::IsAscii(str.start(), str.length())) {
899fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    // If the string is ASCII, we do not need to convert the characters
909fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    // since UTF8 is backwards compatible with ASCII.
919fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    return AllocateStringFromAscii(str, pretenure);
929fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
939fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Non-ASCII and we need to decode.
949fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  return AllocateStringFromUtf8Slow(str, pretenure);
959fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block}
969fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
979fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
985913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Heap::AllocateSymbol(Vector<const char> str,
995913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                  int chars,
1005913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                  uint32_t hash_field) {
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  unibrow::Utf8InputBuffer<> buffer(str.start(),
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                    static_cast<unsigned>(str.length()));
103d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return AllocateInternalSymbol(&buffer, chars, hash_field);
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1079fac840a46e8b7e26894f4792ba26dde14c56b04Steve BlockMaybeObject* Heap::AllocateAsciiSymbol(Vector<const char> str,
1089fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                                       uint32_t hash_field) {
1099fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  if (str.length() > SeqAsciiString::kMaxLength) {
1109fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    return Failure::OutOfMemoryException();
1119fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
1129fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Compute map and object size.
1139fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  Map* map = ascii_symbol_map();
1149fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int size = SeqAsciiString::SizeFor(str.length());
1159fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1169fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Allocate string.
1179fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  Object* result;
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize)
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE)
1209fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                   : old_data_space_->AllocateRaw(size);
1219fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    if (!maybe_result->ToObject(&result)) return maybe_result;
1229fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
1239fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // String maps are all immortal immovable objects.
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map);
1269fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Set length and hash fields of the allocated string.
1279fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  String* answer = String::cast(result);
1289fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  answer->set_length(str.length());
1299fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  answer->set_hash_field(hash_field);
1309fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1319fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  ASSERT_EQ(size, answer->Size());
1329fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1339fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Fill in the characters.
1349fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  memcpy(answer->address() + SeqAsciiString::kHeaderSize,
1359fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block         str.start(), str.length());
1369fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1379fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  return answer;
1389fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block}
1399fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1409fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1419fac840a46e8b7e26894f4792ba26dde14c56b04Steve BlockMaybeObject* Heap::AllocateTwoByteSymbol(Vector<const uc16> str,
1429fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                                         uint32_t hash_field) {
1439fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  if (str.length() > SeqTwoByteString::kMaxLength) {
1449fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    return Failure::OutOfMemoryException();
1459fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
1469fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Compute map and object size.
1479fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  Map* map = symbol_map();
1489fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int size = SeqTwoByteString::SizeFor(str.length());
1499fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1509fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Allocate string.
1519fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  Object* result;
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize)
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE)
1549fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                   : old_data_space_->AllocateRaw(size);
1559fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    if (!maybe_result->ToObject(&result)) return maybe_result;
1569fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
1579fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1589fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  reinterpret_cast<HeapObject*>(result)->set_map(map);
1599fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Set length and hash fields of the allocated string.
1609fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  String* answer = String::cast(result);
1619fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  answer->set_length(str.length());
1629fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  answer->set_hash_field(hash_field);
1639fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1649fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  ASSERT_EQ(size, answer->Size());
1659fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Fill in the characters.
1679fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  memcpy(answer->address() + SeqTwoByteString::kHeaderSize,
1689fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block         str.start(), str.length() * kUC16Size);
1699fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1709fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  return answer;
1719fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block}
1729fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1735913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Heap::CopyFixedArray(FixedArray* src) {
1740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return CopyFixedArrayWithMap(src, src->map());
1750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
1760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
17869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochMaybeObject* Heap::CopyFixedDoubleArray(FixedDoubleArray* src) {
17969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  return CopyFixedDoubleArrayWithMap(src, src->map());
18069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
18169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
18269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
1835913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Heap::AllocateRaw(int size_in_bytes,
1845913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                               AllocationSpace space,
1855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                               AllocationSpace retry_space) {
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(space != NEW_SPACE ||
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block         retry_space == OLD_POINTER_SPACE ||
189e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke         retry_space == OLD_DATA_SPACE ||
190e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke         retry_space == LO_SPACE);
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (FLAG_gc_interval >= 0 &&
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      !disallow_allocation_failure_ &&
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Heap::allocation_timeout_-- <= 0) {
195f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    return Failure::RetryAfterGC(space);
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->counters()->objs_since_last_full()->Increment();
19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->counters()->objs_since_last_young()->Increment();
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2005913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MaybeObject* result;
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (NEW_SPACE == space) {
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = new_space_.AllocateRaw(size_in_bytes);
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (always_allocate() && result->IsFailure()) {
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      space = retry_space;
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return result;
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (OLD_POINTER_SPACE == space) {
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = old_pointer_space_->AllocateRaw(size_in_bytes);
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (OLD_DATA_SPACE == space) {
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = old_data_space_->AllocateRaw(size_in_bytes);
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (CODE_SPACE == space) {
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = code_space_->AllocateRaw(size_in_bytes);
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (LO_SPACE == space) {
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    result = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (CELL_SPACE == space) {
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = cell_space_->AllocateRaw(size_in_bytes);
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(MAP_SPACE == space);
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = map_space_->AllocateRaw(size_in_bytes);
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result->IsFailure()) old_gen_exhausted_ = true;
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMaybeObject* Heap::NumberFromInt32(
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int32_t value, PretenureFlag pretenure) {
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (Smi::IsValid(value)) return Smi::FromInt(value);
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bypass NumberFromDouble to avoid various redundant checks.
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AllocateHeapNumber(FastI2D(value), pretenure);
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMaybeObject* Heap::NumberFromUint32(
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    uint32_t value, PretenureFlag pretenure) {
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if ((int32_t)value >= 0 && Smi::IsValid((int32_t)value)) {
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Smi::FromInt((int32_t)value);
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bypass NumberFromDouble to avoid various redundant checks.
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AllocateHeapNumber(FastUI2D(value), pretenure);
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
247e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Heap::FinalizeExternalString(String* string) {
248e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  ASSERT(string->IsExternalString());
249e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  v8::String::ExternalStringResourceBase** resource_addr =
250e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      reinterpret_cast<v8::String::ExternalStringResourceBase**>(
251e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke          reinterpret_cast<byte*>(string) +
252e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke          ExternalString::kResourceOffset -
253e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke          kHeapObjectTag);
2547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Dispose of the C++ object if it has not already been disposed.
2567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (*resource_addr != NULL) {
2577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    (*resource_addr)->Dispose();
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *resource_addr = NULL;
2597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
260e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
261e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
262e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2635913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Heap::AllocateRawMap() {
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
26544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->counters()->objs_since_last_full()->Increment();
26644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->counters()->objs_since_last_young()->Increment();
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2685913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MaybeObject* result = map_space_->AllocateRaw(Map::kSize);
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result->IsFailure()) old_gen_exhausted_ = true;
270e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef DEBUG
271e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (!result->IsFailure()) {
272e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    // Maps have their own alignment.
2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    CHECK((reinterpret_cast<intptr_t>(result) & kMapAlignmentMask) ==
2746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          static_cast<intptr_t>(kHeapObjectTag));
275e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
276e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2815913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Heap::AllocateRawCell() {
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
28344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->counters()->objs_since_last_full()->Increment();
28444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->counters()->objs_since_last_young()->Increment();
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MaybeObject* result = cell_space_->AllocateRaw(JSGlobalPropertyCell::kSize);
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result->IsFailure()) old_gen_exhausted_ = true;
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Heap::InNewSpace(Object* object) {
2934515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  bool result = new_space_.Contains(object);
2944515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  ASSERT(!result ||                  // Either not in new space
2954515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke         gc_state_ != NOT_IN_GC ||   // ... or in the middle of GC
2964515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke         InToSpace(object));         // ... or in to-space (where we allocate).
2974515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  return result;
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Heap::InNewSpace(Address addr) {
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new_space_.Contains(addr);
3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Heap::InFromSpace(Object* object) {
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return new_space_.FromSpaceContains(object);
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Heap::InToSpace(Object* object) {
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return new_space_.ToSpaceContains(object);
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Heap::OldGenerationAllocationLimitReached() {
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!incremental_marking()->IsStopped()) return false;
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return OldGenerationSpaceAvailable() < 0;
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Heap::ShouldBePromoted(Address old_address, int object_size) {
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // An object should be promoted if:
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - the object has survived a scavenge operation or
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - to space is already 25% full.
3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  NewSpacePage* page = NewSpacePage::FromAddress(old_address);
3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Address age_mark = new_space_.age_mark();
3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool below_mark = page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) &&
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (!page->ContainsLimit(age_mark) || old_address < age_mark);
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return below_mark || (new_space_.Size() + object_size) >=
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        (new_space_.EffectiveCapacity() >> 2);
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Heap::RecordWrite(Address address, int offset) {
3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!InNewSpace(address)) store_buffer_.Mark(address + offset);
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3406ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Heap::RecordWrites(Address address, int start, int len) {
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!InNewSpace(address)) {
3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = 0; i < len; i++) {
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      store_buffer_.Mark(address + start + i * kPointerSize);
3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOldSpace* Heap::TargetSpace(HeapObject* object) {
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InstanceType type = object->map()->instance_type();
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  AllocationSpace space = TargetSpaceId(type);
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return (space == OLD_POINTER_SPACE)
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ? old_pointer_space_
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : old_data_space_;
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAllocationSpace Heap::TargetSpaceId(InstanceType type) {
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Heap numbers and sequential strings are promoted to old data space, all
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // other object types are promoted to old pointer space.  We do not use
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object->IsHeapNumber() and object->IsSeqString() because we already
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // know that object has the heap object tag.
363e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
364e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // These objects are never allocated in new space.
365e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  ASSERT(type != MAP_TYPE);
366e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  ASSERT(type != CODE_TYPE);
367e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  ASSERT(type != ODDBALL_TYPE);
368e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  ASSERT(type != JS_GLOBAL_PROPERTY_CELL_TYPE);
369e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
370e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (type < FIRST_NONSTRING_TYPE) {
37169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // There are four string representations: sequential strings, external
37269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // strings, cons strings, and sliced strings.
37369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Only the latter two contain non-map-word pointers to heap objects.
37469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return ((type & kIsIndirectStringMask) == kIsIndirectStringTag)
375e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        ? OLD_POINTER_SPACE
376e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        : OLD_DATA_SPACE;
377e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  } else {
378e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return (type <= LAST_DATA_TYPE) ? OLD_DATA_SPACE : OLD_POINTER_SPACE;
379e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid Heap::CopyBlock(Address dst, Address src, int byte_size) {
3847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CopyWords(reinterpret_cast<Object**>(dst),
3857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            reinterpret_cast<Object**>(src),
3867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            byte_size / kPointerSize);
3877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
3887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid Heap::MoveBlock(Address dst, Address src, int byte_size) {
3916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(IsAligned(byte_size, kPointerSize));
3926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int size_in_words = byte_size / kPointerSize;
3946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
39518a6f57610d404676fb0db2114fd7ad91e0402b0Ben Murdoch  if ((dst < src) || (dst >= (src + byte_size))) {
3967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    Object** src_slot = reinterpret_cast<Object**>(src);
3977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    Object** dst_slot = reinterpret_cast<Object**>(dst);
3987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    Object** end_slot = src_slot + size_in_words;
3996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    while (src_slot != end_slot) {
4017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      *dst_slot++ = *src_slot++;
4026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
4036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
4046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    memmove(dst, src, byte_size);
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Heap::ScavengePointer(HeapObject** p) {
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ScavengeObject(p, *p);
41144f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
41244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Heap::ScavengeObject(HeapObject** p, HeapObject* object) {
41544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(HEAP->InFromSpace(object));
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We use the first word (where the map pointer usually is) of a heap
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object to record the forwarding pointer.  A forwarding pointer can
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // point to an old space, the code space, or the to space of the new
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // generation.
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MapWord first_word = object->map_word();
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the first word is a forwarding address, the object has already been
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // copied.
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (first_word.IsForwardingAddress()) {
4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HeapObject* dest = first_word.ToForwardingAddress();
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(HEAP->InFromSpace(*p));
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *p = dest;
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call the slow part of scavenge object.
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ScavengeObjectSlow(p, object);
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Heap::CollectGarbage(AllocationSpace space, const char* gc_reason) {
4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const char* collector_reason = NULL;
4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GarbageCollector collector = SelectGarbageCollector(space, &collector_reason);
4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return CollectGarbage(space, collector, gc_reason, collector_reason);
4413e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
4423e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
4433e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
4445913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Heap::PrepareForCompare(String* str) {
4456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Always flatten small strings and force flattening of long strings
4466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // after we have accumulated a certain amount we failed to flatten.
4476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kMaxAlwaysFlattenLength = 32;
4486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kFlattenLongThreshold = 16*KB;
4496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const int length = str->length();
4515913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MaybeObject* obj = str->TryFlatten();
4526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (length <= kMaxAlwaysFlattenLength ||
4536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      unflattened_strings_length_ >= kFlattenLongThreshold) {
4546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return obj;
4556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
4566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (obj->IsFailure()) {
4576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    unflattened_strings_length_ += length;
4586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
4596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return str;
4606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Heap::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(HasBeenSetUp());
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int amount = amount_of_external_allocated_memory_ + change_in_bytes;
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (change_in_bytes >= 0) {
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Avoid overflow.
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (amount > amount_of_external_allocated_memory_) {
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      amount_of_external_allocated_memory_ = amount;
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int amount_since_last_global_gc =
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        amount_of_external_allocated_memory_ -
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        amount_of_external_allocated_memory_at_last_global_gc_;
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (amount_since_last_global_gc > external_allocation_limit_) {
4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      CollectAllGarbage(kNoGCFlags, "external memory allocation limit reached");
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Avoid underflow.
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (amount >= 0) {
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      amount_of_external_allocated_memory_ = amount;
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(amount_of_external_allocated_memory_ >= 0);
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return amount_of_external_allocated_memory_;
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Heap::SetLastScriptId(Object* last_script_id) {
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  roots_[kLastScriptIdRootIndex] = last_script_id;
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
49344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockIsolate* Heap::isolate() {
49444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return reinterpret_cast<Isolate*>(reinterpret_cast<intptr_t>(this) -
49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      reinterpret_cast<size_t>(reinterpret_cast<Isolate*>(4)->heap()) + 4);
49644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
49744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
499f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#ifdef DEBUG
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define GC_GREEDY_CHECK() \
50144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (FLAG_gc_greedy) HEAP->GarbageCollectionGreedyCheck()
502f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#else
503f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#define GC_GREEDY_CHECK() { }
504f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#endif
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Calls the FUNCTION_CALL function and retries it up to three times
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to guarantee that any allocations performed during the call will
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// succeed if there's enough memory.
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5105913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// Warning: Do not use the identifiers __object__, __maybe_object__ or
5115913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// __scope__ in a call to this macro.
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY)\
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  do {                                                                    \
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    GC_GREEDY_CHECK();                                                    \
5165913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    MaybeObject* __maybe_object__ = FUNCTION_CALL;                        \
5175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* __object__ = NULL;                                            \
5185913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE;            \
5195913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (__maybe_object__->IsOutOfMemory()) {                              \
520bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch      v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0", true);\
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }                                                                     \
5225913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY;                \
52344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ISOLATE->heap()->CollectGarbage(Failure::cast(__maybe_object__)->     \
5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    allocation_space(),                   \
5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    "allocation failure");                \
5265913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    __maybe_object__ = FUNCTION_CALL;                                     \
5275913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE;            \
5285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (__maybe_object__->IsOutOfMemory()) {                              \
529bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch      v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1", true);\
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }                                                                     \
5315913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY;                \
53244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ISOLATE->counters()->gc_last_resort_from_handles()->Increment();      \
5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ISOLATE->heap()->CollectAllAvailableGarbage("last resort gc");        \
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {                                                                     \
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      AlwaysAllocateScope __scope__;                                      \
5365913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      __maybe_object__ = FUNCTION_CALL;                                   \
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }                                                                     \
5385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE;            \
5395913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (__maybe_object__->IsOutOfMemory() ||                              \
5405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        __maybe_object__->IsRetryAfterGC()) {                             \
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      /* TODO(1181417): Fix this. */                                      \
542bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch      v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2", true);\
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }                                                                     \
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RETURN_EMPTY;                                                         \
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } while (false)
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE)       \
54944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_AND_RETRY(ISOLATE,                                      \
55044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                 FUNCTION_CALL,                                \
55144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                 return Handle<TYPE>(TYPE::cast(__object__), ISOLATE),  \
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                 return Handle<TYPE>())
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL) \
55644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, return, return)
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinline bool Heap::allow_allocation(bool new_state) {
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool old = allocation_allowed_;
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  allocation_allowed_ = new_state;
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return old;
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
570e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid ExternalStringTable::AddString(String* string) {
571e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  ASSERT(string->IsExternalString());
57244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (heap_->InNewSpace(string)) {
573e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    new_space_strings_.Add(string);
574e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  } else {
575e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    old_space_strings_.Add(string);
576e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
577e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
578e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
579e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
580e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid ExternalStringTable::Iterate(ObjectVisitor* v) {
581e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (!new_space_strings_.is_empty()) {
582e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    Object** start = &new_space_strings_[0];
583e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    v->VisitPointers(start, start + new_space_strings_.length());
584e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
585e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (!old_space_strings_.is_empty()) {
586e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    Object** start = &old_space_strings_[0];
587e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    v->VisitPointers(start, start + old_space_strings_.length());
588e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
589e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
590e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
591e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
592e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Verify() is inline to avoid ifdef-s around its calls in release
593e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// mode.
594e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid ExternalStringTable::Verify() {
595e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef DEBUG
596e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  for (int i = 0; i < new_space_strings_.length(); ++i) {
59744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(heap_->InNewSpace(new_space_strings_[i]));
5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(new_space_strings_[i] != HEAP->raw_unchecked_the_hole_value());
599e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
600e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  for (int i = 0; i < old_space_strings_.length(); ++i) {
60144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(old_space_strings_[i] != HEAP->raw_unchecked_the_hole_value());
603e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
604e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif
605e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
606e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
607e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
608e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid ExternalStringTable::AddOldString(String* string) {
609e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  ASSERT(string->IsExternalString());
61044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!heap_->InNewSpace(string));
611e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  old_space_strings_.Add(string);
612e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
613e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
614e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
615e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid ExternalStringTable::ShrinkNewStrings(int position) {
616e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  new_space_strings_.Rewind(position);
6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_verify_heap) {
6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Verify();
6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
620e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
621e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
62244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
62344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Heap::ClearInstanceofCache() {
62444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  set_instanceof_cache_function(the_hole_value());
62544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
62644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
62744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
62844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockObject* Heap::ToBoolean(bool condition) {
62944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return condition ? true_value() : false_value();
63044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
63144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
63244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
63344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Heap::CompletelyClearInstanceofCache() {
63444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  set_instanceof_cache_map(the_hole_value());
63544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  set_instanceof_cache_function(the_hole_value());
63644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
63744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
63944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockMaybeObject* TranscendentalCache::Get(Type type, double input) {
64044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SubCache* cache = caches_[type];
64144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (cache == NULL) {
64244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    caches_[type] = cache = new SubCache(type);
64344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
64444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return cache->Get(input);
64544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
64644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
64744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
64844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockAddress TranscendentalCache::cache_array_address() {
64944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return reinterpret_cast<Address>(caches_);
65044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
65144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
65244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
65344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockdouble TranscendentalCache::SubCache::Calculate(double input) {
65444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  switch (type_) {
65544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case ACOS:
65644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return acos(input);
65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case ASIN:
65844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return asin(input);
65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case ATAN:
66044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return atan(input);
66144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case COS:
6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return fast_cos(input);
66344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case EXP:
66444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return exp(input);
66544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case LOG:
6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return fast_log(input);
66744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case SIN:
6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return fast_sin(input);
66944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case TAN:
6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return fast_tan(input);
67144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    default:
67244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return 0.0;  // Never happens.
67344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
67644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
67744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockMaybeObject* TranscendentalCache::SubCache::Get(double input) {
67844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Converter c;
67944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  c.dbl = input;
68044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int hash = Hash(c);
68144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Element e = elements_[hash];
68244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (e.in[0] == c.integers[0] &&
68344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      e.in[1] == c.integers[1]) {
68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(e.output != NULL);
68544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate_->counters()->transcendental_cache_hit()->Increment();
68644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return e.output;
68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
68844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  double answer = Calculate(input);
68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->counters()->transcendental_cache_miss()->Increment();
69044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* heap_number;
69144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { MaybeObject* maybe_heap_number =
69244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        isolate_->heap()->AllocateHeapNumber(answer);
69344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (!maybe_heap_number->ToObject(&heap_number)) return maybe_heap_number;
69444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  elements_[hash].in[0] = c.integers[0];
69644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  elements_[hash].in[1] = c.integers[1];
69744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  elements_[hash].output = heap_number;
69844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return heap_number;
69944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
70044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
70144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochAlwaysAllocateScope::AlwaysAllocateScope() {
7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // We shouldn't hit any nested scopes, because that requires
7043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // non-handle code to call handle code. The code still works but
7053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // performance will degrade, so we want to catch this situation
7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in debug mode.
7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(HEAP->always_allocate_scope_depth_ == 0);
7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->always_allocate_scope_depth_++;
7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochAlwaysAllocateScope::~AlwaysAllocateScope() {
7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->always_allocate_scope_depth_--;
7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(HEAP->always_allocate_scope_depth_ == 0);
7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLinearAllocationScope::LinearAllocationScope() {
7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->linear_allocation_scope_depth_++;
7203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLinearAllocationScope::~LinearAllocationScope() {
7243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->linear_allocation_scope_depth_--;
7253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(HEAP->linear_allocation_scope_depth_ >= 0);
7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid VerifyPointersVisitor::VisitPointers(Object** start, Object** end) {
7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (Object** current = start; current < end; current++) {
7323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if ((*current)->IsHeapObject()) {
7333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      HeapObject* object = HeapObject::cast(*current);
7343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ASSERT(HEAP->Contains(object));
7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ASSERT(object->map()->IsMap());
7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochdouble GCTracer::SizeOfHeapObjects() {
7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (static_cast<double>(HEAP->SizeOfObjects())) / MB;
7445d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
7455d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
7465d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
7475d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#ifdef DEBUG
7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDisallowAllocationFailure::DisallowAllocationFailure() {
7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  old_state_ = HEAP->disallow_allocation_failure_;
7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->disallow_allocation_failure_ = true;
7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDisallowAllocationFailure::~DisallowAllocationFailure() {
7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->disallow_allocation_failure_ = old_state_;
7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7575d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#endif
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochAssertNoAllocation::AssertNoAllocation() {
7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  old_state_ = HEAP->allow_allocation(false);
7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochAssertNoAllocation::~AssertNoAllocation() {
7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->allow_allocation(old_state_);
7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDisableAssertNoAllocation::DisableAssertNoAllocation() {
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  old_state_ = HEAP->allow_allocation(true);
7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDisableAssertNoAllocation::~DisableAssertNoAllocation() {
7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->allow_allocation(old_state_);
7785d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
7795d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#else
7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochAssertNoAllocation::AssertNoAllocation() { }
7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochAssertNoAllocation::~AssertNoAllocation() { }
7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDisableAssertNoAllocation::DisableAssertNoAllocation() { }
7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDisableAssertNoAllocation::~DisableAssertNoAllocation() { }
7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7895d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_HEAP_INL_H_
793