1e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Copyright 2007-2010 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#include <signal.h> 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "sys/stat.h" 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ic-inl.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "runtime.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "serialize.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scopeinfo.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "snapshot.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cctest.h" 40e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include "spaces.h" 41e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include "objects.h" 42d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "natives.h" 43d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "bootstrapper.h" 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace v8::internal; 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const unsigned kCounters = 256; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int local_counters[kCounters]; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char* local_counter_names[kCounters]; 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic unsigned CounterHash(const char* s) { 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned hash = 0; 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (*++s) { 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block hash |= hash << 5; 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block hash += *s; 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return hash; 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Callback receiver to track counters in test. 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int* counter_function(const char* name) { 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned hash = CounterHash(name) % kCounters; 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned original_hash = hash; 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(original_hash); 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (local_counter_names[hash] == name) { 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return &local_counters[hash]; 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (local_counter_names[hash] == 0) { 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block local_counter_names[hash] = name; 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return &local_counters[hash]; 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (strcmp(local_counter_names[hash], name) == 0) { 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return &local_counters[hash]; 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block hash = (hash + 1) % kCounters; 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(hash != original_hash); // Hash table has been filled up. 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <class T> 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Address AddressOf(T id) { 8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ExternalReference(id, i::Isolate::Current()).address(); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <class T> 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic uint32_t Encode(const ExternalReferenceEncoder& encoder, T id) { 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return encoder.Encode(AddressOf(id)); 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int make_code(TypeCode type, int id) { 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<uint32_t>(type) << kReferenceTypeShift | id; 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ExternalReferenceEncoder) { 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = i::Isolate::Current(); 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stats_table()->SetCounterFunction(counter_function); 10469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::V8::Initialize(); 10569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExternalReferenceEncoder encoder; 10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(make_code(BUILTIN, Builtins::kArrayCode), 10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Encode(encoder, Builtins::kArrayCode)); 109e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort), 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Encode(encoder, Runtime::kAbort)); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(make_code(IC_UTILITY, IC::kLoadCallbackProperty), 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Encode(encoder, IC_Utility(IC::kLoadCallbackProperty))); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExternalReference keyed_load_function_prototype = 11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(isolate->counters()->keyed_load_function_prototype()); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(make_code(STATS_COUNTER, Counters::k_keyed_load_function_prototype), 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block encoder.Encode(keyed_load_function_prototype.address())); 117d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ExternalReference stack_limit_address = 11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference::address_of_stack_limit(isolate); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(make_code(UNCLASSIFIED, 4), 120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block encoder.Encode(stack_limit_address.address())); 121d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ExternalReference real_stack_limit_address = 12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference::address_of_real_stack_limit(isolate); 123d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(make_code(UNCLASSIFIED, 5), 124d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block encoder.Encode(real_stack_limit_address.address())); 1259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#ifdef ENABLE_DEBUGGER_SUPPORT 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(make_code(UNCLASSIFIED, 16), 12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block encoder.Encode(ExternalReference::debug_break(isolate).address())); 1289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#endif // ENABLE_DEBUGGER_SUPPORT 1299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_EQ(make_code(UNCLASSIFIED, 10), 13044f0eee88ff00398ff7f715fab053374d808c90dSteve Block encoder.Encode( 13144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference::new_space_start(isolate).address())); 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(make_code(UNCLASSIFIED, 3), 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch encoder.Encode( 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference::roots_array_start(isolate).address())); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ExternalReferenceDecoder) { 13944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = i::Isolate::Current(); 14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stats_table()->SetCounterFunction(counter_function); 14169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::V8::Initialize(); 14269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExternalReferenceDecoder decoder; 14444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(AddressOf(Builtins::kArrayCode), 14544f0eee88ff00398ff7f715fab053374d808c90dSteve Block decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode))); 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(AddressOf(Runtime::kAbort), 147e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION, 148e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Runtime::kAbort))); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(AddressOf(IC_Utility(IC::kLoadCallbackProperty)), 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block decoder.Decode(make_code(IC_UTILITY, IC::kLoadCallbackProperty))); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExternalReference keyed_load_function = 15244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference(isolate->counters()->keyed_load_function_prototype()); 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(keyed_load_function.address(), 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block decoder.Decode( 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block make_code(STATS_COUNTER, 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::k_keyed_load_function_prototype))); 15744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(), 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block decoder.Decode(make_code(UNCLASSIFIED, 4))); 15944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(), 160d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block decoder.Decode(make_code(UNCLASSIFIED, 5))); 1619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#ifdef ENABLE_DEBUGGER_SUPPORT 16244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(ExternalReference::debug_break(isolate).address(), 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch decoder.Decode(make_code(UNCLASSIFIED, 16))); 1649dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#endif // ENABLE_DEBUGGER_SUPPORT 16544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(ExternalReference::new_space_start(isolate).address(), 1669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen decoder.Decode(make_code(UNCLASSIFIED, 10))); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass FileByteSink : public SnapshotByteSink { 171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke public: 172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke explicit FileByteSink(const char* snapshot_file) { 173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fp_ = OS::FOpen(snapshot_file, "wb"); 174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke file_name_ = snapshot_file; 175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (fp_ == NULL) { 176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file); 177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke exit(1); 178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual ~FileByteSink() { 181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (fp_ != NULL) { 182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fclose(fp_); 183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual void Put(int byte, const char* description) { 186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (fp_ != NULL) { 187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fputc(byte, fp_); 188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual int Position() { 191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return ftell(fp_); 192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void WriteSpaceUsed( 194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int new_space_used, 195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int pointer_space_used, 196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int data_space_used, 197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int code_space_used, 198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int map_space_used, 199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int cell_space_used, 200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int large_space_used); 201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private: 203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke FILE* fp_; 204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* file_name_; 205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}; 206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FileByteSink::WriteSpaceUsed( 209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int new_space_used, 210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int pointer_space_used, 211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int data_space_used, 212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int code_space_used, 213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int map_space_used, 214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int cell_space_used, 215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int large_space_used) { 216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int file_name_length = StrLength(file_name_) + 10; 217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Vector<char> name = Vector<char>::New(file_name_length + 1); 218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke OS::SNPrintF(name, "%s.size", file_name_); 219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke FILE* fp = OS::FOpen(name.start(), "w"); 2203e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu name.Dispose(); 221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fprintf(fp, "new %d\n", new_space_used); 222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fprintf(fp, "pointer %d\n", pointer_space_used); 223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fprintf(fp, "data %d\n", data_space_used); 224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fprintf(fp, "code %d\n", code_space_used); 225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fprintf(fp, "map %d\n", map_space_used); 226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fprintf(fp, "cell %d\n", cell_space_used); 227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fprintf(fp, "large %d\n", large_space_used); 228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke fclose(fp); 229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkestatic bool WriteToFile(const char* snapshot_file) { 233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke FileByteSink file(snapshot_file); 234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StartupSerializer ser(&file); 235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ser.Serialize(); 236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return true; 237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Serialize() { 241d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // We have to create one context. One reason for this is so that the builtins 242d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // can be loaded from v8natives.js and their addresses can be processed. This 243d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // will clear the pending fixups array, which would otherwise contain GC roots 244d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // that would confuse the serialization/deserialization process. 245d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Persistent<v8::Context> env = v8::Context::New(); 246d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env.Dispose(); 247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke WriteToFile(FLAG_testing_serialization_file); 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 251d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Test that the whole heap can be serialized. 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(Serialize) { 253d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Serializer::Enable(); 254d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::V8::Initialize(); 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Serialize(); 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 259d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Test that heap serialization is non-destructive. 260d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(SerializeTwice) { 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Serializer::Enable(); 262d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::V8::Initialize(); 263d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Serialize(); 264d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Serialize(); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//---------------------------------------------------------------------------- 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that the heap can be deserialized. 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Deserialize() { 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(Snapshot::Initialize(FLAG_testing_serialization_file)); 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void SanityCheck() { 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->Verify(); 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 28144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(Isolate::Current()->global()->IsJSObject()); 28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(Isolate::Current()->global_context()->IsContext()); 28344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(HEAP->symbol_table()->IsSymbolTable()); 28444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!FACTORY->LookupAsciiSymbol("Empty")->IsFailure()); 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockDEPENDENT_TEST(Deserialize, Serialize) { 2893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // The serialize-deserialize tests only work if the VM is built without 2903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // serialization. That doesn't matter. We don't need to be able to 2913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // serialize a snapshot in a VM that is booted from a snapshot. 2923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (!Snapshot::IsEnabled()) { 2933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::HandleScope scope; 2943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Deserialize(); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::Persistent<v8::Context> env = v8::Context::New(); 2973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu env->Enter(); 298d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 2993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SanityCheck(); 3003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 304d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockDEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) { 3053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (!Snapshot::IsEnabled()) { 3063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::HandleScope scope; 3073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Deserialize(); 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::Persistent<v8::Context> env = v8::Context::New(); 3103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu env->Enter(); 311d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SanityCheck(); 3133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 317d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockDEPENDENT_TEST(DeserializeAndRunScript2, Serialize) { 3183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (!Snapshot::IsEnabled()) { 3193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::HandleScope scope; 3203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Deserialize(); 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::Persistent<v8::Context> env = v8::Context::New(); 3233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu env->Enter(); 324d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu const char* c_source = "\"1234\".length"; 3263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::Local<v8::String> source = v8::String::New(c_source); 3273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::Local<v8::Script> script = v8::Script::Compile(source); 3283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK_EQ(4, script->Run()->Int32Value()); 3293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockDEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2, 334d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SerializeTwice) { 3353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (!Snapshot::IsEnabled()) { 3363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::HandleScope scope; 3373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Deserialize(); 338d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::Persistent<v8::Context> env = v8::Context::New(); 3403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu env->Enter(); 341d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu const char* c_source = "\"1234\".length"; 3433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::Local<v8::String> source = v8::String::New(c_source); 3443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::Local<v8::Script> script = v8::Script::Compile(source); 3453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK_EQ(4, script->Run()->Int32Value()); 3463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(PartialSerialization) { 351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Serializer::Enable(); 352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::V8::Initialize(); 353d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::Persistent<v8::Context> env = v8::Context::New(); 355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(!env.IsEmpty()); 356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke env->Enter(); 357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Make sure all builtin scripts are cached. 358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { HandleScope scope; 359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->bootstrapper()->NativesSourceLookup(i); 361eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke } 362e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Object* raw_foo; 367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::HandleScope handle_scope; 369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::Local<v8::String> foo = v8::String::New("foo"); 370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(!foo.IsEmpty()); 371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke raw_foo = *(v8::Utils::OpenHandle(*foo)); 372eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke } 373e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; 375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Vector<char> startup_name = Vector<char>::New(file_name_length + 1); 376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); 377e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke env->Exit(); 379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke env.Dispose(); 380e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 381d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke FileByteSink startup_sink(startup_name.start()); 3823e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu startup_name.Dispose(); 383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StartupSerializer startup_serializer(&startup_sink); 384d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke startup_serializer.SerializeStrongReferences(); 385d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 386d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke FileByteSink partial_sink(FLAG_testing_serialization_file); 387d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke PartialSerializer p_ser(&startup_serializer, &partial_sink); 388d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke p_ser.Serialize(&raw_foo); 389d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke startup_serializer.SerializeWeakReferences(); 390d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE), 391d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE), 392d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke p_ser.CurrentAllocationAddress(OLD_DATA_SPACE), 393d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke p_ser.CurrentAllocationAddress(CODE_SPACE), 394d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke p_ser.CurrentAllocationAddress(MAP_SPACE), 395d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke p_ser.CurrentAllocationAddress(CELL_SPACE), 396d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke p_ser.CurrentAllocationAddress(LO_SPACE)); 397e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 398e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 399e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic void ReserveSpaceForPartialSnapshot(const char* file_name) { 4013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int file_name_length = StrLength(file_name) + 10; 402e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Vector<char> name = Vector<char>::New(file_name_length + 1); 403e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke OS::SNPrintF(name, "%s.size", file_name); 404e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke FILE* fp = OS::FOpen(name.start(), "r"); 4053e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu name.Dispose(); 406e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int new_size, pointer_size, data_size, code_size, map_size, cell_size; 407e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int large_size; 408e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef _MSC_VER 409e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Avoid warning about unsafe fscanf from MSVC. 410e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Please note that this is only fine if %c and %s are not being used. 411e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#define fscanf fscanf_s 412e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif 413e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size)); 414e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size)); 415e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size)); 416e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size)); 417e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size)); 418e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size)); 419e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(1, fscanf(fp, "large %d\n", &large_size)); 420e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef _MSC_VER 421e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#undef fscanf 422e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif 423e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke fclose(fp); 42444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->ReserveSpace(new_size, 425e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke pointer_size, 426e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke data_size, 427e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke code_size, 428e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke map_size, 429e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke cell_size, 430e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke large_size); 4313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuDEPENDENT_TEST(PartialDeserialization, PartialSerialization) { 4353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (!Snapshot::IsEnabled()) { 4363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; 4373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Vector<char> startup_name = Vector<char>::New(file_name_length + 1); 4383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); 4393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK(Snapshot::Initialize(startup_name.start())); 4413e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu startup_name.Dispose(); 4423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu const char* file_name = FLAG_testing_serialization_file; 4443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ReserveSpaceForPartialSnapshot(file_name); 4453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int snapshot_size = 0; 4473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu byte* snapshot = ReadBytes(file_name, &snapshot_size); 4483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Object* root; 4503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu { 4513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SnapshotByteSource source(snapshot, snapshot_size); 4523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Deserializer deserializer(&source); 4533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu deserializer.DeserializePartial(&root); 4543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK(root->IsString()); 4553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 4563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::HandleScope handle_scope; 45769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> root_handle(root); 45869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 45969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ReserveSpaceForPartialSnapshot(file_name); 4603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Object* root2; 4623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu { 4633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SnapshotByteSource source(snapshot, snapshot_size); 4643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Deserializer deserializer(&source); 4653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu deserializer.DeserializePartial(&root2); 4663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK(root2->IsString()); 4673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK(*root_handle == root2); 4683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 469d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 4703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 471d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuTEST(ContextSerialization) { 4743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Serializer::Enable(); 4753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::V8::Initialize(); 4763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::Persistent<v8::Context> env = v8::Context::New(); 4783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(!env.IsEmpty()); 4793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu env->Enter(); 4803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Make sure all builtin scripts are cached. 4813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu { HandleScope scope; 4823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { 48344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->bootstrapper()->NativesSourceLookup(i); 4843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 4853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 4863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // If we don't do this then we end up with a stray root pointing at the 4873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // context even after we have disposed of env. 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 4893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; 4913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Vector<char> startup_name = Vector<char>::New(file_name_length + 1); 4923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); 4933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu env->Exit(); 4953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Object* raw_context = *(v8::Utils::OpenHandle(*env)); 4973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu env.Dispose(); 4993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FileByteSink startup_sink(startup_name.start()); 5013e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu startup_name.Dispose(); 5023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu StartupSerializer startup_serializer(&startup_sink); 5033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu startup_serializer.SerializeStrongReferences(); 5043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FileByteSink partial_sink(FLAG_testing_serialization_file); 5063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu PartialSerializer p_ser(&startup_serializer, &partial_sink); 5073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu p_ser.Serialize(&raw_context); 5083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu startup_serializer.SerializeWeakReferences(); 5093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE), 5103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE), 5113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu p_ser.CurrentAllocationAddress(OLD_DATA_SPACE), 5123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu p_ser.CurrentAllocationAddress(CODE_SPACE), 5133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu p_ser.CurrentAllocationAddress(MAP_SPACE), 5143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu p_ser.CurrentAllocationAddress(CELL_SPACE), 5153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu p_ser.CurrentAllocationAddress(LO_SPACE)); 5163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 5173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuDEPENDENT_TEST(ContextDeserialization, ContextSerialization) { 5203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (!Snapshot::IsEnabled()) { 5213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; 5223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Vector<char> startup_name = Vector<char>::New(file_name_length + 1); 5233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); 5243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK(Snapshot::Initialize(startup_name.start())); 5263e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu startup_name.Dispose(); 5273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu const char* file_name = FLAG_testing_serialization_file; 5293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ReserveSpaceForPartialSnapshot(file_name); 5303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int snapshot_size = 0; 5323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu byte* snapshot = ReadBytes(file_name, &snapshot_size); 5333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Object* root; 5353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu { 5363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SnapshotByteSource source(snapshot, snapshot_size); 5373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Deserializer deserializer(&source); 5383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu deserializer.DeserializePartial(&root); 5393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK(root->IsContext()); 5403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 5413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::HandleScope handle_scope; 54269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> root_handle(root); 54369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 54469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ReserveSpaceForPartialSnapshot(file_name); 5453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Object* root2; 5473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu { 5483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SnapshotByteSource source(snapshot, snapshot_size); 5493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Deserializer deserializer(&source); 5503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu deserializer.DeserializePartial(&root2); 5513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK(root2->IsContext()); 5523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CHECK(*root_handle != root2); 5533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 554d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 555e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 556e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 557e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 558e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeTEST(LinearAllocation) { 559e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::V8::Initialize(); 560e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int new_space_max = 512 * KB; 5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int paged_space_max = Page::kMaxNonCodeHeapObjectSize; 5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int code_space_max = HEAP->code_space()->AreaSize(); 5633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 564e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int size = 1000; size < 5 * MB; size += size >> 1) { 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch size &= ~8; // Round. 566e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int new_space_size = (size < new_space_max) ? size : new_space_max; 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int paged_space_size = (size < paged_space_max) ? size : paged_space_max; 56844f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->ReserveSpace( 569e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke new_space_size, 5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch paged_space_size, // Old pointer space. 5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch paged_space_size, // Old data space. 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->code_space()->RoundSizeDownToObjectAlignment(code_space_max), 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->map_space()->RoundSizeDownToObjectAlignment(paged_space_size), 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->cell_space()->RoundSizeDownToObjectAlignment(paged_space_size), 575e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke size); // Large object space. 576e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke LinearAllocationScope linear_allocation_scope; 577e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kSmallFixedArrayLength = 4; 578e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kSmallFixedArraySize = 579e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke FixedArray::kHeaderSize + kSmallFixedArrayLength * kPointerSize; 580e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kSmallStringLength = 16; 581e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kSmallStringSize = 5826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block (SeqAsciiString::kHeaderSize + kSmallStringLength + 5836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kObjectAlignmentMask) & ~kObjectAlignmentMask; 584e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kMapSize = Map::kSize; 585e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 586e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* new_last = NULL; 587e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int i = 0; 588e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke i + kSmallFixedArraySize <= new_space_size; 589e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke i += kSmallFixedArraySize) { 5905913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Object* obj = 59144f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->AllocateFixedArray(kSmallFixedArrayLength)->ToObjectChecked(); 592e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (new_last != NULL) { 5936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(reinterpret_cast<char*>(obj) == 5946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block reinterpret_cast<char*>(new_last) + kSmallFixedArraySize); 595e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 596e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke new_last = obj; 597e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 598e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 599e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* pointer_last = NULL; 600e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int i = 0; 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i + kSmallFixedArraySize <= paged_space_size; 602e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke i += kSmallFixedArraySize) { 60344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* obj = HEAP->AllocateFixedArray(kSmallFixedArrayLength, 6045913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck TENURED)->ToObjectChecked(); 605e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int old_page_fullness = i % Page::kPageSize; 606e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int page_fullness = (i + kSmallFixedArraySize) % Page::kPageSize; 607e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (page_fullness < old_page_fullness || 6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch page_fullness > HEAP->old_pointer_space()->AreaSize()) { 609e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke i = RoundUp(i, Page::kPageSize); 610e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke pointer_last = NULL; 611e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 612e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (pointer_last != NULL) { 6136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(reinterpret_cast<char*>(obj) == 6146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block reinterpret_cast<char*>(pointer_last) + kSmallFixedArraySize); 615e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 616e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke pointer_last = obj; 617e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 618e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 619e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* data_last = NULL; 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i + kSmallStringSize <= paged_space_size; 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i += kSmallStringSize) { 62344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* obj = HEAP->AllocateRawAsciiString(kSmallStringLength, 6245913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck TENURED)->ToObjectChecked(); 625e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int old_page_fullness = i % Page::kPageSize; 626e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int page_fullness = (i + kSmallStringSize) % Page::kPageSize; 627e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (page_fullness < old_page_fullness || 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch page_fullness > HEAP->old_data_space()->AreaSize()) { 629e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke i = RoundUp(i, Page::kPageSize); 630e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke data_last = NULL; 631e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 632e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (data_last != NULL) { 6336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(reinterpret_cast<char*>(obj) == 6346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block reinterpret_cast<char*>(data_last) + kSmallStringSize); 635e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 636e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke data_last = obj; 637e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 638e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 639e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* map_last = NULL; 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i + kMapSize <= paged_space_size; i += kMapSize) { 64144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* obj = HEAP->AllocateMap(JS_OBJECT_TYPE, 6425913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 42 * kPointerSize)->ToObjectChecked(); 643e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int old_page_fullness = i % Page::kPageSize; 644e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int page_fullness = (i + kMapSize) % Page::kPageSize; 645e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (page_fullness < old_page_fullness || 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch page_fullness > HEAP->map_space()->AreaSize()) { 647e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke i = RoundUp(i, Page::kPageSize); 648e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke map_last = NULL; 649e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 650e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (map_last != NULL) { 6516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(reinterpret_cast<char*>(obj) == 6526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block reinterpret_cast<char*>(map_last) + kMapSize); 653e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 654e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke map_last = obj; 655e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 656e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (size > Page::kMaxNonCodeHeapObjectSize) { 658e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Support for reserving space in large object space is not there yet, 659e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // but using an always-allocate scope is fine for now. 660e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke AlwaysAllocateScope always; 661e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int large_object_array_length = 662e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke (size - FixedArray::kHeaderSize) / kPointerSize; 66344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* obj = HEAP->AllocateFixedArray(large_object_array_length, 6645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck TENURED)->ToObjectChecked(); 665e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK(!obj->IsFailure()); 666e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 667e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 668e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 669e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 670e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(TestThatAlwaysSucceeds) { 6723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 6733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(TestThatAlwaysFails) { 6763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool ArtificialFailure = false; 6773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(ArtificialFailure); 6783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 6793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockDEPENDENT_TEST(DependentTestThatAlwaysFails, TestThatAlwaysSucceeds) { 6823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool ArtificialFailure2 = false; 6833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(ArtificialFailure2); 6843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 685