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 the_hole_value_location =
    118       ExternalReference::the_hole_value_location(isolate);
    119   CHECK_EQ(make_code(UNCLASSIFIED, 2),
    120            encoder.Encode(the_hole_value_location.address()));
    121   ExternalReference stack_limit_address =
    122       ExternalReference::address_of_stack_limit(isolate);
    123   CHECK_EQ(make_code(UNCLASSIFIED, 4),
    124            encoder.Encode(stack_limit_address.address()));
    125   ExternalReference real_stack_limit_address =
    126       ExternalReference::address_of_real_stack_limit(isolate);
    127   CHECK_EQ(make_code(UNCLASSIFIED, 5),
    128            encoder.Encode(real_stack_limit_address.address()));
    129 #ifdef ENABLE_DEBUGGER_SUPPORT
    130   CHECK_EQ(make_code(UNCLASSIFIED, 15),
    131            encoder.Encode(ExternalReference::debug_break(isolate).address()));
    132 #endif  // ENABLE_DEBUGGER_SUPPORT
    133   CHECK_EQ(make_code(UNCLASSIFIED, 10),
    134            encoder.Encode(
    135                ExternalReference::new_space_start(isolate).address()));
    136   CHECK_EQ(make_code(UNCLASSIFIED, 3),
    137            encoder.Encode(ExternalReference::roots_address(isolate).address()));
    138 }
    139 
    140 
    141 TEST(ExternalReferenceDecoder) {
    142   Isolate* isolate = i::Isolate::Current();
    143   isolate->stats_table()->SetCounterFunction(counter_function);
    144   v8::V8::Initialize();
    145 
    146   ExternalReferenceDecoder decoder;
    147   CHECK_EQ(AddressOf(Builtins::kArrayCode),
    148            decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode)));
    149   CHECK_EQ(AddressOf(Runtime::kAbort),
    150            decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION,
    151                                     Runtime::kAbort)));
    152   CHECK_EQ(AddressOf(IC_Utility(IC::kLoadCallbackProperty)),
    153            decoder.Decode(make_code(IC_UTILITY, IC::kLoadCallbackProperty)));
    154   ExternalReference keyed_load_function =
    155       ExternalReference(isolate->counters()->keyed_load_function_prototype());
    156   CHECK_EQ(keyed_load_function.address(),
    157            decoder.Decode(
    158                make_code(STATS_COUNTER,
    159                          Counters::k_keyed_load_function_prototype)));
    160   CHECK_EQ(ExternalReference::the_hole_value_location(isolate).address(),
    161            decoder.Decode(make_code(UNCLASSIFIED, 2)));
    162   CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(),
    163            decoder.Decode(make_code(UNCLASSIFIED, 4)));
    164   CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(),
    165            decoder.Decode(make_code(UNCLASSIFIED, 5)));
    166 #ifdef ENABLE_DEBUGGER_SUPPORT
    167   CHECK_EQ(ExternalReference::debug_break(isolate).address(),
    168            decoder.Decode(make_code(UNCLASSIFIED, 15)));
    169 #endif  // ENABLE_DEBUGGER_SUPPORT
    170   CHECK_EQ(ExternalReference::new_space_start(isolate).address(),
    171            decoder.Decode(make_code(UNCLASSIFIED, 10)));
    172 }
    173 
    174 
    175 class FileByteSink : public SnapshotByteSink {
    176  public:
    177   explicit FileByteSink(const char* snapshot_file) {
    178     fp_ = OS::FOpen(snapshot_file, "wb");
    179     file_name_ = snapshot_file;
    180     if (fp_ == NULL) {
    181       PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
    182       exit(1);
    183     }
    184   }
    185   virtual ~FileByteSink() {
    186     if (fp_ != NULL) {
    187       fclose(fp_);
    188     }
    189   }
    190   virtual void Put(int byte, const char* description) {
    191     if (fp_ != NULL) {
    192       fputc(byte, fp_);
    193     }
    194   }
    195   virtual int Position() {
    196     return ftell(fp_);
    197   }
    198   void WriteSpaceUsed(
    199       int new_space_used,
    200       int pointer_space_used,
    201       int data_space_used,
    202       int code_space_used,
    203       int map_space_used,
    204       int cell_space_used,
    205       int large_space_used);
    206 
    207  private:
    208   FILE* fp_;
    209   const char* file_name_;
    210 };
    211 
    212 
    213 void FileByteSink::WriteSpaceUsed(
    214       int new_space_used,
    215       int pointer_space_used,
    216       int data_space_used,
    217       int code_space_used,
    218       int map_space_used,
    219       int cell_space_used,
    220       int large_space_used) {
    221   int file_name_length = StrLength(file_name_) + 10;
    222   Vector<char> name = Vector<char>::New(file_name_length + 1);
    223   OS::SNPrintF(name, "%s.size", file_name_);
    224   FILE* fp = OS::FOpen(name.start(), "w");
    225   name.Dispose();
    226   fprintf(fp, "new %d\n", new_space_used);
    227   fprintf(fp, "pointer %d\n", pointer_space_used);
    228   fprintf(fp, "data %d\n", data_space_used);
    229   fprintf(fp, "code %d\n", code_space_used);
    230   fprintf(fp, "map %d\n", map_space_used);
    231   fprintf(fp, "cell %d\n", cell_space_used);
    232   fprintf(fp, "large %d\n", large_space_used);
    233   fclose(fp);
    234 }
    235 
    236 
    237 static bool WriteToFile(const char* snapshot_file) {
    238   FileByteSink file(snapshot_file);
    239   StartupSerializer ser(&file);
    240   ser.Serialize();
    241   return true;
    242 }
    243 
    244 
    245 static void Serialize() {
    246   // We have to create one context.  One reason for this is so that the builtins
    247   // can be loaded from v8natives.js and their addresses can be processed.  This
    248   // will clear the pending fixups array, which would otherwise contain GC roots
    249   // that would confuse the serialization/deserialization process.
    250   v8::Persistent<v8::Context> env = v8::Context::New();
    251   env.Dispose();
    252   WriteToFile(FLAG_testing_serialization_file);
    253 }
    254 
    255 
    256 // Test that the whole heap can be serialized.
    257 TEST(Serialize) {
    258   Serializer::Enable();
    259   v8::V8::Initialize();
    260   Serialize();
    261 }
    262 
    263 
    264 // Test that heap serialization is non-destructive.
    265 TEST(SerializeTwice) {
    266   Serializer::Enable();
    267   v8::V8::Initialize();
    268   Serialize();
    269   Serialize();
    270 }
    271 
    272 
    273 //----------------------------------------------------------------------------
    274 // Tests that the heap can be deserialized.
    275 
    276 static void Deserialize() {
    277   CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
    278 }
    279 
    280 
    281 static void SanityCheck() {
    282   v8::HandleScope scope;
    283 #ifdef DEBUG
    284   HEAP->Verify();
    285 #endif
    286   CHECK(Isolate::Current()->global()->IsJSObject());
    287   CHECK(Isolate::Current()->global_context()->IsContext());
    288   CHECK(HEAP->symbol_table()->IsSymbolTable());
    289   CHECK(!FACTORY->LookupAsciiSymbol("Empty")->IsFailure());
    290 }
    291 
    292 
    293 DEPENDENT_TEST(Deserialize, Serialize) {
    294   // The serialize-deserialize tests only work if the VM is built without
    295   // serialization.  That doesn't matter.  We don't need to be able to
    296   // serialize a snapshot in a VM that is booted from a snapshot.
    297   if (!Snapshot::IsEnabled()) {
    298     v8::HandleScope scope;
    299     Deserialize();
    300 
    301     v8::Persistent<v8::Context> env = v8::Context::New();
    302     env->Enter();
    303 
    304     SanityCheck();
    305   }
    306 }
    307 
    308 
    309 DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
    310   if (!Snapshot::IsEnabled()) {
    311     v8::HandleScope scope;
    312     Deserialize();
    313 
    314     v8::Persistent<v8::Context> env = v8::Context::New();
    315     env->Enter();
    316 
    317     SanityCheck();
    318   }
    319 }
    320 
    321 
    322 DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
    323   if (!Snapshot::IsEnabled()) {
    324     v8::HandleScope scope;
    325     Deserialize();
    326 
    327     v8::Persistent<v8::Context> env = v8::Context::New();
    328     env->Enter();
    329 
    330     const char* c_source = "\"1234\".length";
    331     v8::Local<v8::String> source = v8::String::New(c_source);
    332     v8::Local<v8::Script> script = v8::Script::Compile(source);
    333     CHECK_EQ(4, script->Run()->Int32Value());
    334   }
    335 }
    336 
    337 
    338 DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
    339                SerializeTwice) {
    340   if (!Snapshot::IsEnabled()) {
    341     v8::HandleScope scope;
    342     Deserialize();
    343 
    344     v8::Persistent<v8::Context> env = v8::Context::New();
    345     env->Enter();
    346 
    347     const char* c_source = "\"1234\".length";
    348     v8::Local<v8::String> source = v8::String::New(c_source);
    349     v8::Local<v8::Script> script = v8::Script::Compile(source);
    350     CHECK_EQ(4, script->Run()->Int32Value());
    351   }
    352 }
    353 
    354 
    355 TEST(PartialSerialization) {
    356   Serializer::Enable();
    357   v8::V8::Initialize();
    358 
    359   v8::Persistent<v8::Context> env = v8::Context::New();
    360   ASSERT(!env.IsEmpty());
    361   env->Enter();
    362   // Make sure all builtin scripts are cached.
    363   { HandleScope scope;
    364     for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
    365       Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
    366     }
    367   }
    368   HEAP->CollectAllGarbage(true);
    369   HEAP->CollectAllGarbage(true);
    370 
    371   Object* raw_foo;
    372   {
    373     v8::HandleScope handle_scope;
    374     v8::Local<v8::String> foo = v8::String::New("foo");
    375     ASSERT(!foo.IsEmpty());
    376     raw_foo = *(v8::Utils::OpenHandle(*foo));
    377   }
    378 
    379   int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    380   Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    381   OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
    382 
    383   env->Exit();
    384   env.Dispose();
    385 
    386   FileByteSink startup_sink(startup_name.start());
    387   startup_name.Dispose();
    388   StartupSerializer startup_serializer(&startup_sink);
    389   startup_serializer.SerializeStrongReferences();
    390 
    391   FileByteSink partial_sink(FLAG_testing_serialization_file);
    392   PartialSerializer p_ser(&startup_serializer, &partial_sink);
    393   p_ser.Serialize(&raw_foo);
    394   startup_serializer.SerializeWeakReferences();
    395   partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
    396                               p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
    397                               p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
    398                               p_ser.CurrentAllocationAddress(CODE_SPACE),
    399                               p_ser.CurrentAllocationAddress(MAP_SPACE),
    400                               p_ser.CurrentAllocationAddress(CELL_SPACE),
    401                               p_ser.CurrentAllocationAddress(LO_SPACE));
    402 }
    403 
    404 
    405 static void ReserveSpaceForPartialSnapshot(const char* file_name) {
    406   int file_name_length = StrLength(file_name) + 10;
    407   Vector<char> name = Vector<char>::New(file_name_length + 1);
    408   OS::SNPrintF(name, "%s.size", file_name);
    409   FILE* fp = OS::FOpen(name.start(), "r");
    410   name.Dispose();
    411   int new_size, pointer_size, data_size, code_size, map_size, cell_size;
    412   int large_size;
    413 #ifdef _MSC_VER
    414   // Avoid warning about unsafe fscanf from MSVC.
    415   // Please note that this is only fine if %c and %s are not being used.
    416 #define fscanf fscanf_s
    417 #endif
    418   CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
    419   CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
    420   CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
    421   CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
    422   CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
    423   CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
    424   CHECK_EQ(1, fscanf(fp, "large %d\n", &large_size));
    425 #ifdef _MSC_VER
    426 #undef fscanf
    427 #endif
    428   fclose(fp);
    429   HEAP->ReserveSpace(new_size,
    430                      pointer_size,
    431                      data_size,
    432                      code_size,
    433                      map_size,
    434                      cell_size,
    435                      large_size);
    436 }
    437 
    438 
    439 DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
    440   if (!Snapshot::IsEnabled()) {
    441     int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    442     Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    443     OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
    444 
    445     CHECK(Snapshot::Initialize(startup_name.start()));
    446     startup_name.Dispose();
    447 
    448     const char* file_name = FLAG_testing_serialization_file;
    449     ReserveSpaceForPartialSnapshot(file_name);
    450 
    451     int snapshot_size = 0;
    452     byte* snapshot = ReadBytes(file_name, &snapshot_size);
    453 
    454     Object* root;
    455     {
    456       SnapshotByteSource source(snapshot, snapshot_size);
    457       Deserializer deserializer(&source);
    458       deserializer.DeserializePartial(&root);
    459       CHECK(root->IsString());
    460     }
    461     v8::HandleScope handle_scope;
    462     Handle<Object>root_handle(root);
    463 
    464     Object* root2;
    465     {
    466       SnapshotByteSource source(snapshot, snapshot_size);
    467       Deserializer deserializer(&source);
    468       deserializer.DeserializePartial(&root2);
    469       CHECK(root2->IsString());
    470       CHECK(*root_handle == root2);
    471     }
    472   }
    473 }
    474 
    475 
    476 TEST(ContextSerialization) {
    477   Serializer::Enable();
    478   v8::V8::Initialize();
    479 
    480   v8::Persistent<v8::Context> env = v8::Context::New();
    481   ASSERT(!env.IsEmpty());
    482   env->Enter();
    483   // Make sure all builtin scripts are cached.
    484   { HandleScope scope;
    485     for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
    486       Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
    487     }
    488   }
    489   // If we don't do this then we end up with a stray root pointing at the
    490   // context even after we have disposed of env.
    491   HEAP->CollectAllGarbage(true);
    492 
    493   int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    494   Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    495   OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
    496 
    497   env->Exit();
    498 
    499   Object* raw_context = *(v8::Utils::OpenHandle(*env));
    500 
    501   env.Dispose();
    502 
    503   FileByteSink startup_sink(startup_name.start());
    504   startup_name.Dispose();
    505   StartupSerializer startup_serializer(&startup_sink);
    506   startup_serializer.SerializeStrongReferences();
    507 
    508   FileByteSink partial_sink(FLAG_testing_serialization_file);
    509   PartialSerializer p_ser(&startup_serializer, &partial_sink);
    510   p_ser.Serialize(&raw_context);
    511   startup_serializer.SerializeWeakReferences();
    512   partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
    513                               p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
    514                               p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
    515                               p_ser.CurrentAllocationAddress(CODE_SPACE),
    516                               p_ser.CurrentAllocationAddress(MAP_SPACE),
    517                               p_ser.CurrentAllocationAddress(CELL_SPACE),
    518                               p_ser.CurrentAllocationAddress(LO_SPACE));
    519 }
    520 
    521 
    522 DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
    523   if (!Snapshot::IsEnabled()) {
    524     int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    525     Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    526     OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
    527 
    528     CHECK(Snapshot::Initialize(startup_name.start()));
    529     startup_name.Dispose();
    530 
    531     const char* file_name = FLAG_testing_serialization_file;
    532     ReserveSpaceForPartialSnapshot(file_name);
    533 
    534     int snapshot_size = 0;
    535     byte* snapshot = ReadBytes(file_name, &snapshot_size);
    536 
    537     Object* root;
    538     {
    539       SnapshotByteSource source(snapshot, snapshot_size);
    540       Deserializer deserializer(&source);
    541       deserializer.DeserializePartial(&root);
    542       CHECK(root->IsContext());
    543     }
    544     v8::HandleScope handle_scope;
    545     Handle<Object>root_handle(root);
    546 
    547     Object* root2;
    548     {
    549       SnapshotByteSource source(snapshot, snapshot_size);
    550       Deserializer deserializer(&source);
    551       deserializer.DeserializePartial(&root2);
    552       CHECK(root2->IsContext());
    553       CHECK(*root_handle != root2);
    554     }
    555   }
    556 }
    557 
    558 
    559 TEST(LinearAllocation) {
    560   v8::V8::Initialize();
    561   int new_space_max = 512 * KB;
    562 
    563   for (int size = 1000; size < 5 * MB; size += size >> 1) {
    564     int new_space_size = (size < new_space_max) ? size : new_space_max;
    565     HEAP->ReserveSpace(
    566         new_space_size,
    567         size,              // Old pointer space.
    568         size,              // Old data space.
    569         size,              // Code space.
    570         size,              // Map space.
    571         size,              // Cell space.
    572         size);             // Large object space.
    573     LinearAllocationScope linear_allocation_scope;
    574     const int kSmallFixedArrayLength = 4;
    575     const int kSmallFixedArraySize =
    576         FixedArray::kHeaderSize + kSmallFixedArrayLength * kPointerSize;
    577     const int kSmallStringLength = 16;
    578     const int kSmallStringSize =
    579         (SeqAsciiString::kHeaderSize + kSmallStringLength +
    580         kObjectAlignmentMask) & ~kObjectAlignmentMask;
    581     const int kMapSize = Map::kSize;
    582 
    583     Object* new_last = NULL;
    584     for (int i = 0;
    585          i + kSmallFixedArraySize <= new_space_size;
    586          i += kSmallFixedArraySize) {
    587       Object* obj =
    588           HEAP->AllocateFixedArray(kSmallFixedArrayLength)->ToObjectChecked();
    589       if (new_last != NULL) {
    590         CHECK(reinterpret_cast<char*>(obj) ==
    591               reinterpret_cast<char*>(new_last) + kSmallFixedArraySize);
    592       }
    593       new_last = obj;
    594     }
    595 
    596     Object* pointer_last = NULL;
    597     for (int i = 0;
    598          i + kSmallFixedArraySize <= size;
    599          i += kSmallFixedArraySize) {
    600       Object* obj = HEAP->AllocateFixedArray(kSmallFixedArrayLength,
    601                                              TENURED)->ToObjectChecked();
    602       int old_page_fullness = i % Page::kPageSize;
    603       int page_fullness = (i + kSmallFixedArraySize) % Page::kPageSize;
    604       if (page_fullness < old_page_fullness ||
    605           page_fullness > Page::kObjectAreaSize) {
    606         i = RoundUp(i, Page::kPageSize);
    607         pointer_last = NULL;
    608       }
    609       if (pointer_last != NULL) {
    610         CHECK(reinterpret_cast<char*>(obj) ==
    611               reinterpret_cast<char*>(pointer_last) + kSmallFixedArraySize);
    612       }
    613       pointer_last = obj;
    614     }
    615 
    616     Object* data_last = NULL;
    617     for (int i = 0; i + kSmallStringSize <= size; i += kSmallStringSize) {
    618       Object* obj = HEAP->AllocateRawAsciiString(kSmallStringLength,
    619                                                  TENURED)->ToObjectChecked();
    620       int old_page_fullness = i % Page::kPageSize;
    621       int page_fullness = (i + kSmallStringSize) % Page::kPageSize;
    622       if (page_fullness < old_page_fullness ||
    623           page_fullness > Page::kObjectAreaSize) {
    624         i = RoundUp(i, Page::kPageSize);
    625         data_last = NULL;
    626       }
    627       if (data_last != NULL) {
    628         CHECK(reinterpret_cast<char*>(obj) ==
    629               reinterpret_cast<char*>(data_last) + kSmallStringSize);
    630       }
    631       data_last = obj;
    632     }
    633 
    634     Object* map_last = NULL;
    635     for (int i = 0; i + kMapSize <= size; i += kMapSize) {
    636       Object* obj = HEAP->AllocateMap(JS_OBJECT_TYPE,
    637                                       42 * kPointerSize)->ToObjectChecked();
    638       int old_page_fullness = i % Page::kPageSize;
    639       int page_fullness = (i + kMapSize) % Page::kPageSize;
    640       if (page_fullness < old_page_fullness ||
    641           page_fullness > Page::kObjectAreaSize) {
    642         i = RoundUp(i, Page::kPageSize);
    643         map_last = NULL;
    644       }
    645       if (map_last != NULL) {
    646         CHECK(reinterpret_cast<char*>(obj) ==
    647               reinterpret_cast<char*>(map_last) + kMapSize);
    648       }
    649       map_last = obj;
    650     }
    651 
    652     if (size > Page::kObjectAreaSize) {
    653       // Support for reserving space in large object space is not there yet,
    654       // but using an always-allocate scope is fine for now.
    655       AlwaysAllocateScope always;
    656       int large_object_array_length =
    657           (size - FixedArray::kHeaderSize) / kPointerSize;
    658       Object* obj = HEAP->AllocateFixedArray(large_object_array_length,
    659                                              TENURED)->ToObjectChecked();
    660       CHECK(!obj->IsFailure());
    661     }
    662   }
    663 }
    664 
    665 
    666 TEST(TestThatAlwaysSucceeds) {
    667 }
    668 
    669 
    670 TEST(TestThatAlwaysFails) {
    671   bool ArtificialFailure = false;
    672   CHECK(ArtificialFailure);
    673 }
    674 
    675 
    676 DEPENDENT_TEST(DependentTestThatAlwaysFails, TestThatAlwaysSucceeds) {
    677   bool ArtificialFailure2 = false;
    678   CHECK(ArtificialFailure2);
    679 }
    680