Home | History | Annotate | Download | only in cctest
      1 // Copyright 2007-2010 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include <signal.h>
     29 
     30 #include "sys/stat.h"
     31 #include "v8.h"
     32 
     33 #include "debug.h"
     34 #include "ic-inl.h"
     35 #include "runtime.h"
     36 #include "serialize.h"
     37 #include "scopeinfo.h"
     38 #include "snapshot.h"
     39 #include "cctest.h"
     40 #include "spaces.h"
     41 #include "objects.h"
     42 #include "natives.h"
     43 #include "bootstrapper.h"
     44 
     45 using namespace v8::internal;
     46 
     47 static const unsigned kCounters = 256;
     48 static int local_counters[kCounters];
     49 static const char* local_counter_names[kCounters];
     50 
     51 
     52 static unsigned CounterHash(const char* s) {
     53   unsigned hash = 0;
     54   while (*++s) {
     55     hash |= hash << 5;
     56     hash += *s;
     57   }
     58   return hash;
     59 }
     60 
     61 
     62 // Callback receiver to track counters in test.
     63 static int* counter_function(const char* name) {
     64   unsigned hash = CounterHash(name) % kCounters;
     65   unsigned original_hash = hash;
     66   USE(original_hash);
     67   while (true) {
     68     if (local_counter_names[hash] == name) {
     69       return &local_counters[hash];
     70     }
     71     if (local_counter_names[hash] == 0) {
     72       local_counter_names[hash] = name;
     73       return &local_counters[hash];
     74     }
     75     if (strcmp(local_counter_names[hash], name) == 0) {
     76       return &local_counters[hash];
     77     }
     78     hash = (hash + 1) % kCounters;
     79     ASSERT(hash != original_hash);  // Hash table has been filled up.
     80   }
     81 }
     82 
     83 
     84 template <class T>
     85 static Address AddressOf(T id) {
     86   return ExternalReference(id, i::Isolate::Current()).address();
     87 }
     88 
     89 
     90 template <class T>
     91 static uint32_t Encode(const ExternalReferenceEncoder& encoder, T id) {
     92   return encoder.Encode(AddressOf(id));
     93 }
     94 
     95 
     96 static int make_code(TypeCode type, int id) {
     97   return static_cast<uint32_t>(type) << kReferenceTypeShift | id;
     98 }
     99 
    100 
    101 TEST(ExternalReferenceEncoder) {
    102   Isolate* isolate = i::Isolate::Current();
    103   isolate->stats_table()->SetCounterFunction(counter_function);
    104   v8::V8::Initialize();
    105 
    106   ExternalReferenceEncoder encoder;
    107   CHECK_EQ(make_code(BUILTIN, Builtins::kArrayCode),
    108            Encode(encoder, Builtins::kArrayCode));
    109   CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort),
    110            Encode(encoder, Runtime::kAbort));
    111   CHECK_EQ(make_code(IC_UTILITY, IC::kLoadCallbackProperty),
    112            Encode(encoder, IC_Utility(IC::kLoadCallbackProperty)));
    113   ExternalReference keyed_load_function_prototype =
    114       ExternalReference(isolate->counters()->keyed_load_function_prototype());
    115   CHECK_EQ(make_code(STATS_COUNTER, Counters::k_keyed_load_function_prototype),
    116            encoder.Encode(keyed_load_function_prototype.address()));
    117   ExternalReference stack_limit_address =
    118       ExternalReference::address_of_stack_limit(isolate);
    119   CHECK_EQ(make_code(UNCLASSIFIED, 4),
    120            encoder.Encode(stack_limit_address.address()));
    121   ExternalReference real_stack_limit_address =
    122       ExternalReference::address_of_real_stack_limit(isolate);
    123   CHECK_EQ(make_code(UNCLASSIFIED, 5),
    124            encoder.Encode(real_stack_limit_address.address()));
    125 #ifdef ENABLE_DEBUGGER_SUPPORT
    126   CHECK_EQ(make_code(UNCLASSIFIED, 16),
    127            encoder.Encode(ExternalReference::debug_break(isolate).address()));
    128 #endif  // ENABLE_DEBUGGER_SUPPORT
    129   CHECK_EQ(make_code(UNCLASSIFIED, 10),
    130            encoder.Encode(
    131                ExternalReference::new_space_start(isolate).address()));
    132   CHECK_EQ(make_code(UNCLASSIFIED, 3),
    133            encoder.Encode(
    134                ExternalReference::roots_array_start(isolate).address()));
    135 }
    136 
    137 
    138 TEST(ExternalReferenceDecoder) {
    139   Isolate* isolate = i::Isolate::Current();
    140   isolate->stats_table()->SetCounterFunction(counter_function);
    141   v8::V8::Initialize();
    142 
    143   ExternalReferenceDecoder decoder;
    144   CHECK_EQ(AddressOf(Builtins::kArrayCode),
    145            decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode)));
    146   CHECK_EQ(AddressOf(Runtime::kAbort),
    147            decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION,
    148                                     Runtime::kAbort)));
    149   CHECK_EQ(AddressOf(IC_Utility(IC::kLoadCallbackProperty)),
    150            decoder.Decode(make_code(IC_UTILITY, IC::kLoadCallbackProperty)));
    151   ExternalReference keyed_load_function =
    152       ExternalReference(isolate->counters()->keyed_load_function_prototype());
    153   CHECK_EQ(keyed_load_function.address(),
    154            decoder.Decode(
    155                make_code(STATS_COUNTER,
    156                          Counters::k_keyed_load_function_prototype)));
    157   CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(),
    158            decoder.Decode(make_code(UNCLASSIFIED, 4)));
    159   CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(),
    160            decoder.Decode(make_code(UNCLASSIFIED, 5)));
    161 #ifdef ENABLE_DEBUGGER_SUPPORT
    162   CHECK_EQ(ExternalReference::debug_break(isolate).address(),
    163            decoder.Decode(make_code(UNCLASSIFIED, 16)));
    164 #endif  // ENABLE_DEBUGGER_SUPPORT
    165   CHECK_EQ(ExternalReference::new_space_start(isolate).address(),
    166            decoder.Decode(make_code(UNCLASSIFIED, 10)));
    167 }
    168 
    169 
    170 class FileByteSink : public SnapshotByteSink {
    171  public:
    172   explicit FileByteSink(const char* snapshot_file) {
    173     fp_ = OS::FOpen(snapshot_file, "wb");
    174     file_name_ = snapshot_file;
    175     if (fp_ == NULL) {
    176       PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
    177       exit(1);
    178     }
    179   }
    180   virtual ~FileByteSink() {
    181     if (fp_ != NULL) {
    182       fclose(fp_);
    183     }
    184   }
    185   virtual void Put(int byte, const char* description) {
    186     if (fp_ != NULL) {
    187       fputc(byte, fp_);
    188     }
    189   }
    190   virtual int Position() {
    191     return ftell(fp_);
    192   }
    193   void WriteSpaceUsed(
    194       int new_space_used,
    195       int pointer_space_used,
    196       int data_space_used,
    197       int code_space_used,
    198       int map_space_used,
    199       int cell_space_used,
    200       int large_space_used);
    201 
    202  private:
    203   FILE* fp_;
    204   const char* file_name_;
    205 };
    206 
    207 
    208 void FileByteSink::WriteSpaceUsed(
    209       int new_space_used,
    210       int pointer_space_used,
    211       int data_space_used,
    212       int code_space_used,
    213       int map_space_used,
    214       int cell_space_used,
    215       int large_space_used) {
    216   int file_name_length = StrLength(file_name_) + 10;
    217   Vector<char> name = Vector<char>::New(file_name_length + 1);
    218   OS::SNPrintF(name, "%s.size", file_name_);
    219   FILE* fp = OS::FOpen(name.start(), "w");
    220   name.Dispose();
    221   fprintf(fp, "new %d\n", new_space_used);
    222   fprintf(fp, "pointer %d\n", pointer_space_used);
    223   fprintf(fp, "data %d\n", data_space_used);
    224   fprintf(fp, "code %d\n", code_space_used);
    225   fprintf(fp, "map %d\n", map_space_used);
    226   fprintf(fp, "cell %d\n", cell_space_used);
    227   fprintf(fp, "large %d\n", large_space_used);
    228   fclose(fp);
    229 }
    230 
    231 
    232 static bool WriteToFile(const char* snapshot_file) {
    233   FileByteSink file(snapshot_file);
    234   StartupSerializer ser(&file);
    235   ser.Serialize();
    236   return true;
    237 }
    238 
    239 
    240 static void Serialize() {
    241   // We have to create one context.  One reason for this is so that the builtins
    242   // can be loaded from v8natives.js and their addresses can be processed.  This
    243   // will clear the pending fixups array, which would otherwise contain GC roots
    244   // that would confuse the serialization/deserialization process.
    245   v8::Persistent<v8::Context> env = v8::Context::New();
    246   env.Dispose();
    247   WriteToFile(FLAG_testing_serialization_file);
    248 }
    249 
    250 
    251 // Test that the whole heap can be serialized.
    252 TEST(Serialize) {
    253   Serializer::Enable();
    254   v8::V8::Initialize();
    255   Serialize();
    256 }
    257 
    258 
    259 // Test that heap serialization is non-destructive.
    260 TEST(SerializeTwice) {
    261   Serializer::Enable();
    262   v8::V8::Initialize();
    263   Serialize();
    264   Serialize();
    265 }
    266 
    267 
    268 //----------------------------------------------------------------------------
    269 // Tests that the heap can be deserialized.
    270 
    271 static void Deserialize() {
    272   CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
    273 }
    274 
    275 
    276 static void SanityCheck() {
    277   v8::HandleScope scope;
    278 #ifdef DEBUG
    279   HEAP->Verify();
    280 #endif
    281   CHECK(Isolate::Current()->global()->IsJSObject());
    282   CHECK(Isolate::Current()->global_context()->IsContext());
    283   CHECK(HEAP->symbol_table()->IsSymbolTable());
    284   CHECK(!FACTORY->LookupAsciiSymbol("Empty")->IsFailure());
    285 }
    286 
    287 
    288 DEPENDENT_TEST(Deserialize, Serialize) {
    289   // The serialize-deserialize tests only work if the VM is built without
    290   // serialization.  That doesn't matter.  We don't need to be able to
    291   // serialize a snapshot in a VM that is booted from a snapshot.
    292   if (!Snapshot::IsEnabled()) {
    293     v8::HandleScope scope;
    294     Deserialize();
    295 
    296     v8::Persistent<v8::Context> env = v8::Context::New();
    297     env->Enter();
    298 
    299     SanityCheck();
    300   }
    301 }
    302 
    303 
    304 DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
    305   if (!Snapshot::IsEnabled()) {
    306     v8::HandleScope scope;
    307     Deserialize();
    308 
    309     v8::Persistent<v8::Context> env = v8::Context::New();
    310     env->Enter();
    311 
    312     SanityCheck();
    313   }
    314 }
    315 
    316 
    317 DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
    318   if (!Snapshot::IsEnabled()) {
    319     v8::HandleScope scope;
    320     Deserialize();
    321 
    322     v8::Persistent<v8::Context> env = v8::Context::New();
    323     env->Enter();
    324 
    325     const char* c_source = "\"1234\".length";
    326     v8::Local<v8::String> source = v8::String::New(c_source);
    327     v8::Local<v8::Script> script = v8::Script::Compile(source);
    328     CHECK_EQ(4, script->Run()->Int32Value());
    329   }
    330 }
    331 
    332 
    333 DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
    334                SerializeTwice) {
    335   if (!Snapshot::IsEnabled()) {
    336     v8::HandleScope scope;
    337     Deserialize();
    338 
    339     v8::Persistent<v8::Context> env = v8::Context::New();
    340     env->Enter();
    341 
    342     const char* c_source = "\"1234\".length";
    343     v8::Local<v8::String> source = v8::String::New(c_source);
    344     v8::Local<v8::Script> script = v8::Script::Compile(source);
    345     CHECK_EQ(4, script->Run()->Int32Value());
    346   }
    347 }
    348 
    349 
    350 TEST(PartialSerialization) {
    351   Serializer::Enable();
    352   v8::V8::Initialize();
    353 
    354   v8::Persistent<v8::Context> env = v8::Context::New();
    355   ASSERT(!env.IsEmpty());
    356   env->Enter();
    357   // Make sure all builtin scripts are cached.
    358   { HandleScope scope;
    359     for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
    360       Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
    361     }
    362   }
    363   HEAP->CollectAllGarbage(Heap::kNoGCFlags);
    364   HEAP->CollectAllGarbage(Heap::kNoGCFlags);
    365 
    366   Object* raw_foo;
    367   {
    368     v8::HandleScope handle_scope;
    369     v8::Local<v8::String> foo = v8::String::New("foo");
    370     ASSERT(!foo.IsEmpty());
    371     raw_foo = *(v8::Utils::OpenHandle(*foo));
    372   }
    373 
    374   int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    375   Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    376   OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
    377 
    378   env->Exit();
    379   env.Dispose();
    380 
    381   FileByteSink startup_sink(startup_name.start());
    382   startup_name.Dispose();
    383   StartupSerializer startup_serializer(&startup_sink);
    384   startup_serializer.SerializeStrongReferences();
    385 
    386   FileByteSink partial_sink(FLAG_testing_serialization_file);
    387   PartialSerializer p_ser(&startup_serializer, &partial_sink);
    388   p_ser.Serialize(&raw_foo);
    389   startup_serializer.SerializeWeakReferences();
    390   partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
    391                               p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
    392                               p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
    393                               p_ser.CurrentAllocationAddress(CODE_SPACE),
    394                               p_ser.CurrentAllocationAddress(MAP_SPACE),
    395                               p_ser.CurrentAllocationAddress(CELL_SPACE),
    396                               p_ser.CurrentAllocationAddress(LO_SPACE));
    397 }
    398 
    399 
    400 static void ReserveSpaceForPartialSnapshot(const char* file_name) {
    401   int file_name_length = StrLength(file_name) + 10;
    402   Vector<char> name = Vector<char>::New(file_name_length + 1);
    403   OS::SNPrintF(name, "%s.size", file_name);
    404   FILE* fp = OS::FOpen(name.start(), "r");
    405   name.Dispose();
    406   int new_size, pointer_size, data_size, code_size, map_size, cell_size;
    407   int large_size;
    408 #ifdef _MSC_VER
    409   // Avoid warning about unsafe fscanf from MSVC.
    410   // Please note that this is only fine if %c and %s are not being used.
    411 #define fscanf fscanf_s
    412 #endif
    413   CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
    414   CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
    415   CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
    416   CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
    417   CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
    418   CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
    419   CHECK_EQ(1, fscanf(fp, "large %d\n", &large_size));
    420 #ifdef _MSC_VER
    421 #undef fscanf
    422 #endif
    423   fclose(fp);
    424   HEAP->ReserveSpace(new_size,
    425                      pointer_size,
    426                      data_size,
    427                      code_size,
    428                      map_size,
    429                      cell_size,
    430                      large_size);
    431 }
    432 
    433 
    434 DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
    435   if (!Snapshot::IsEnabled()) {
    436     int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    437     Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    438     OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
    439 
    440     CHECK(Snapshot::Initialize(startup_name.start()));
    441     startup_name.Dispose();
    442 
    443     const char* file_name = FLAG_testing_serialization_file;
    444     ReserveSpaceForPartialSnapshot(file_name);
    445 
    446     int snapshot_size = 0;
    447     byte* snapshot = ReadBytes(file_name, &snapshot_size);
    448 
    449     Object* root;
    450     {
    451       SnapshotByteSource source(snapshot, snapshot_size);
    452       Deserializer deserializer(&source);
    453       deserializer.DeserializePartial(&root);
    454       CHECK(root->IsString());
    455     }
    456     v8::HandleScope handle_scope;
    457     Handle<Object> root_handle(root);
    458 
    459     ReserveSpaceForPartialSnapshot(file_name);
    460 
    461     Object* root2;
    462     {
    463       SnapshotByteSource source(snapshot, snapshot_size);
    464       Deserializer deserializer(&source);
    465       deserializer.DeserializePartial(&root2);
    466       CHECK(root2->IsString());
    467       CHECK(*root_handle == root2);
    468     }
    469   }
    470 }
    471 
    472 
    473 TEST(ContextSerialization) {
    474   Serializer::Enable();
    475   v8::V8::Initialize();
    476 
    477   v8::Persistent<v8::Context> env = v8::Context::New();
    478   ASSERT(!env.IsEmpty());
    479   env->Enter();
    480   // Make sure all builtin scripts are cached.
    481   { HandleScope scope;
    482     for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
    483       Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
    484     }
    485   }
    486   // If we don't do this then we end up with a stray root pointing at the
    487   // context even after we have disposed of env.
    488   HEAP->CollectAllGarbage(Heap::kNoGCFlags);
    489 
    490   int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    491   Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    492   OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
    493 
    494   env->Exit();
    495 
    496   Object* raw_context = *(v8::Utils::OpenHandle(*env));
    497 
    498   env.Dispose();
    499 
    500   FileByteSink startup_sink(startup_name.start());
    501   startup_name.Dispose();
    502   StartupSerializer startup_serializer(&startup_sink);
    503   startup_serializer.SerializeStrongReferences();
    504 
    505   FileByteSink partial_sink(FLAG_testing_serialization_file);
    506   PartialSerializer p_ser(&startup_serializer, &partial_sink);
    507   p_ser.Serialize(&raw_context);
    508   startup_serializer.SerializeWeakReferences();
    509   partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
    510                               p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
    511                               p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
    512                               p_ser.CurrentAllocationAddress(CODE_SPACE),
    513                               p_ser.CurrentAllocationAddress(MAP_SPACE),
    514                               p_ser.CurrentAllocationAddress(CELL_SPACE),
    515                               p_ser.CurrentAllocationAddress(LO_SPACE));
    516 }
    517 
    518 
    519 DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
    520   if (!Snapshot::IsEnabled()) {
    521     int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    522     Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    523     OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
    524 
    525     CHECK(Snapshot::Initialize(startup_name.start()));
    526     startup_name.Dispose();
    527 
    528     const char* file_name = FLAG_testing_serialization_file;
    529     ReserveSpaceForPartialSnapshot(file_name);
    530 
    531     int snapshot_size = 0;
    532     byte* snapshot = ReadBytes(file_name, &snapshot_size);
    533 
    534     Object* root;
    535     {
    536       SnapshotByteSource source(snapshot, snapshot_size);
    537       Deserializer deserializer(&source);
    538       deserializer.DeserializePartial(&root);
    539       CHECK(root->IsContext());
    540     }
    541     v8::HandleScope handle_scope;
    542     Handle<Object> root_handle(root);
    543 
    544     ReserveSpaceForPartialSnapshot(file_name);
    545 
    546     Object* root2;
    547     {
    548       SnapshotByteSource source(snapshot, snapshot_size);
    549       Deserializer deserializer(&source);
    550       deserializer.DeserializePartial(&root2);
    551       CHECK(root2->IsContext());
    552       CHECK(*root_handle != root2);
    553     }
    554   }
    555 }
    556 
    557 
    558 TEST(LinearAllocation) {
    559   v8::V8::Initialize();
    560   int new_space_max = 512 * KB;
    561   int paged_space_max = Page::kMaxNonCodeHeapObjectSize;
    562   int code_space_max = HEAP->code_space()->AreaSize();
    563 
    564   for (int size = 1000; size < 5 * MB; size += size >> 1) {
    565     size &= ~8;  // Round.
    566     int new_space_size = (size < new_space_max) ? size : new_space_max;
    567     int paged_space_size = (size < paged_space_max) ? size : paged_space_max;
    568     HEAP->ReserveSpace(
    569         new_space_size,
    570         paged_space_size,  // Old pointer space.
    571         paged_space_size,  // Old data space.
    572         HEAP->code_space()->RoundSizeDownToObjectAlignment(code_space_max),
    573         HEAP->map_space()->RoundSizeDownToObjectAlignment(paged_space_size),
    574         HEAP->cell_space()->RoundSizeDownToObjectAlignment(paged_space_size),
    575         size);             // Large object space.
    576     LinearAllocationScope linear_allocation_scope;
    577     const int kSmallFixedArrayLength = 4;
    578     const int kSmallFixedArraySize =
    579         FixedArray::kHeaderSize + kSmallFixedArrayLength * kPointerSize;
    580     const int kSmallStringLength = 16;
    581     const int kSmallStringSize =
    582         (SeqAsciiString::kHeaderSize + kSmallStringLength +
    583         kObjectAlignmentMask) & ~kObjectAlignmentMask;
    584     const int kMapSize = Map::kSize;
    585 
    586     Object* new_last = NULL;
    587     for (int i = 0;
    588          i + kSmallFixedArraySize <= new_space_size;
    589          i += kSmallFixedArraySize) {
    590       Object* obj =
    591           HEAP->AllocateFixedArray(kSmallFixedArrayLength)->ToObjectChecked();
    592       if (new_last != NULL) {
    593         CHECK(reinterpret_cast<char*>(obj) ==
    594               reinterpret_cast<char*>(new_last) + kSmallFixedArraySize);
    595       }
    596       new_last = obj;
    597     }
    598 
    599     Object* pointer_last = NULL;
    600     for (int i = 0;
    601          i + kSmallFixedArraySize <= paged_space_size;
    602          i += kSmallFixedArraySize) {
    603       Object* obj = HEAP->AllocateFixedArray(kSmallFixedArrayLength,
    604                                              TENURED)->ToObjectChecked();
    605       int old_page_fullness = i % Page::kPageSize;
    606       int page_fullness = (i + kSmallFixedArraySize) % Page::kPageSize;
    607       if (page_fullness < old_page_fullness ||
    608           page_fullness > HEAP->old_pointer_space()->AreaSize()) {
    609         i = RoundUp(i, Page::kPageSize);
    610         pointer_last = NULL;
    611       }
    612       if (pointer_last != NULL) {
    613         CHECK(reinterpret_cast<char*>(obj) ==
    614               reinterpret_cast<char*>(pointer_last) + kSmallFixedArraySize);
    615       }
    616       pointer_last = obj;
    617     }
    618 
    619     Object* data_last = NULL;
    620     for (int i = 0;
    621          i + kSmallStringSize <= paged_space_size;
    622          i += kSmallStringSize) {
    623       Object* obj = HEAP->AllocateRawAsciiString(kSmallStringLength,
    624                                                  TENURED)->ToObjectChecked();
    625       int old_page_fullness = i % Page::kPageSize;
    626       int page_fullness = (i + kSmallStringSize) % Page::kPageSize;
    627       if (page_fullness < old_page_fullness ||
    628           page_fullness > HEAP->old_data_space()->AreaSize()) {
    629         i = RoundUp(i, Page::kPageSize);
    630         data_last = NULL;
    631       }
    632       if (data_last != NULL) {
    633         CHECK(reinterpret_cast<char*>(obj) ==
    634               reinterpret_cast<char*>(data_last) + kSmallStringSize);
    635       }
    636       data_last = obj;
    637     }
    638 
    639     Object* map_last = NULL;
    640     for (int i = 0; i + kMapSize <= paged_space_size; i += kMapSize) {
    641       Object* obj = HEAP->AllocateMap(JS_OBJECT_TYPE,
    642                                       42 * kPointerSize)->ToObjectChecked();
    643       int old_page_fullness = i % Page::kPageSize;
    644       int page_fullness = (i + kMapSize) % Page::kPageSize;
    645       if (page_fullness < old_page_fullness ||
    646           page_fullness > HEAP->map_space()->AreaSize()) {
    647         i = RoundUp(i, Page::kPageSize);
    648         map_last = NULL;
    649       }
    650       if (map_last != NULL) {
    651         CHECK(reinterpret_cast<char*>(obj) ==
    652               reinterpret_cast<char*>(map_last) + kMapSize);
    653       }
    654       map_last = obj;
    655     }
    656 
    657     if (size > Page::kMaxNonCodeHeapObjectSize) {
    658       // Support for reserving space in large object space is not there yet,
    659       // but using an always-allocate scope is fine for now.
    660       AlwaysAllocateScope always;
    661       int large_object_array_length =
    662           (size - FixedArray::kHeaderSize) / kPointerSize;
    663       Object* obj = HEAP->AllocateFixedArray(large_object_array_length,
    664                                              TENURED)->ToObjectChecked();
    665       CHECK(!obj->IsFailure());
    666     }
    667   }
    668 }
    669 
    670 
    671 TEST(TestThatAlwaysSucceeds) {
    672 }
    673 
    674 
    675 TEST(TestThatAlwaysFails) {
    676   bool ArtificialFailure = false;
    677   CHECK(ArtificialFailure);
    678 }
    679 
    680 
    681 DEPENDENT_TEST(DependentTestThatAlwaysFails, TestThatAlwaysSucceeds) {
    682   bool ArtificialFailure2 = false;
    683   CHECK(ArtificialFailure2);
    684 }
    685