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