// Copyright 2007-2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <signal.h>

#include "sys/stat.h"
#include "v8.h"

#include "debug.h"
#include "ic-inl.h"
#include "runtime.h"
#include "serialize.h"
#include "scopeinfo.h"
#include "snapshot.h"
#include "cctest.h"
#include "spaces.h"
#include "objects.h"
#include "natives.h"
#include "bootstrapper.h"

using namespace v8::internal;

static const unsigned kCounters = 256;
static int local_counters[kCounters];
static const char* local_counter_names[kCounters];


static unsigned CounterHash(const char* s) {
  unsigned hash = 0;
  while (*++s) {
    hash |= hash << 5;
    hash += *s;
  }
  return hash;
}


// Callback receiver to track counters in test.
static int* counter_function(const char* name) {
  unsigned hash = CounterHash(name) % kCounters;
  unsigned original_hash = hash;
  USE(original_hash);
  while (true) {
    if (local_counter_names[hash] == name) {
      return &local_counters[hash];
    }
    if (local_counter_names[hash] == 0) {
      local_counter_names[hash] = name;
      return &local_counters[hash];
    }
    if (strcmp(local_counter_names[hash], name) == 0) {
      return &local_counters[hash];
    }
    hash = (hash + 1) % kCounters;
    ASSERT(hash != original_hash);  // Hash table has been filled up.
  }
}


template <class T>
static Address AddressOf(T id) {
  return ExternalReference(id, i::Isolate::Current()).address();
}


template <class T>
static uint32_t Encode(const ExternalReferenceEncoder& encoder, T id) {
  return encoder.Encode(AddressOf(id));
}


static int make_code(TypeCode type, int id) {
  return static_cast<uint32_t>(type) << kReferenceTypeShift | id;
}


TEST(ExternalReferenceEncoder) {
  Isolate* isolate = i::Isolate::Current();
  isolate->stats_table()->SetCounterFunction(counter_function);
  v8::V8::Initialize();

  ExternalReferenceEncoder encoder;
  CHECK_EQ(make_code(BUILTIN, Builtins::kArrayCode),
           Encode(encoder, Builtins::kArrayCode));
  CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort),
           Encode(encoder, Runtime::kAbort));
  CHECK_EQ(make_code(IC_UTILITY, IC::kLoadCallbackProperty),
           Encode(encoder, IC_Utility(IC::kLoadCallbackProperty)));
  ExternalReference keyed_load_function_prototype =
      ExternalReference(isolate->counters()->keyed_load_function_prototype());
  CHECK_EQ(make_code(STATS_COUNTER, Counters::k_keyed_load_function_prototype),
           encoder.Encode(keyed_load_function_prototype.address()));
  ExternalReference stack_limit_address =
      ExternalReference::address_of_stack_limit(isolate);
  CHECK_EQ(make_code(UNCLASSIFIED, 4),
           encoder.Encode(stack_limit_address.address()));
  ExternalReference real_stack_limit_address =
      ExternalReference::address_of_real_stack_limit(isolate);
  CHECK_EQ(make_code(UNCLASSIFIED, 5),
           encoder.Encode(real_stack_limit_address.address()));
#ifdef ENABLE_DEBUGGER_SUPPORT
  CHECK_EQ(make_code(UNCLASSIFIED, 16),
           encoder.Encode(ExternalReference::debug_break(isolate).address()));
#endif  // ENABLE_DEBUGGER_SUPPORT
  CHECK_EQ(make_code(UNCLASSIFIED, 10),
           encoder.Encode(
               ExternalReference::new_space_start(isolate).address()));
  CHECK_EQ(make_code(UNCLASSIFIED, 3),
           encoder.Encode(
               ExternalReference::roots_array_start(isolate).address()));
}


TEST(ExternalReferenceDecoder) {
  Isolate* isolate = i::Isolate::Current();
  isolate->stats_table()->SetCounterFunction(counter_function);
  v8::V8::Initialize();

  ExternalReferenceDecoder decoder;
  CHECK_EQ(AddressOf(Builtins::kArrayCode),
           decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode)));
  CHECK_EQ(AddressOf(Runtime::kAbort),
           decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION,
                                    Runtime::kAbort)));
  CHECK_EQ(AddressOf(IC_Utility(IC::kLoadCallbackProperty)),
           decoder.Decode(make_code(IC_UTILITY, IC::kLoadCallbackProperty)));
  ExternalReference keyed_load_function =
      ExternalReference(isolate->counters()->keyed_load_function_prototype());
  CHECK_EQ(keyed_load_function.address(),
           decoder.Decode(
               make_code(STATS_COUNTER,
                         Counters::k_keyed_load_function_prototype)));
  CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(),
           decoder.Decode(make_code(UNCLASSIFIED, 4)));
  CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(),
           decoder.Decode(make_code(UNCLASSIFIED, 5)));
#ifdef ENABLE_DEBUGGER_SUPPORT
  CHECK_EQ(ExternalReference::debug_break(isolate).address(),
           decoder.Decode(make_code(UNCLASSIFIED, 16)));
#endif  // ENABLE_DEBUGGER_SUPPORT
  CHECK_EQ(ExternalReference::new_space_start(isolate).address(),
           decoder.Decode(make_code(UNCLASSIFIED, 10)));
}


class FileByteSink : public SnapshotByteSink {
 public:
  explicit FileByteSink(const char* snapshot_file) {
    fp_ = OS::FOpen(snapshot_file, "wb");
    file_name_ = snapshot_file;
    if (fp_ == NULL) {
      PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
      exit(1);
    }
  }
  virtual ~FileByteSink() {
    if (fp_ != NULL) {
      fclose(fp_);
    }
  }
  virtual void Put(int byte, const char* description) {
    if (fp_ != NULL) {
      fputc(byte, fp_);
    }
  }
  virtual int Position() {
    return ftell(fp_);
  }
  void WriteSpaceUsed(
      int new_space_used,
      int pointer_space_used,
      int data_space_used,
      int code_space_used,
      int map_space_used,
      int cell_space_used,
      int large_space_used);

 private:
  FILE* fp_;
  const char* file_name_;
};


void FileByteSink::WriteSpaceUsed(
      int new_space_used,
      int pointer_space_used,
      int data_space_used,
      int code_space_used,
      int map_space_used,
      int cell_space_used,
      int large_space_used) {
  int file_name_length = StrLength(file_name_) + 10;
  Vector<char> name = Vector<char>::New(file_name_length + 1);
  OS::SNPrintF(name, "%s.size", file_name_);
  FILE* fp = OS::FOpen(name.start(), "w");
  name.Dispose();
  fprintf(fp, "new %d\n", new_space_used);
  fprintf(fp, "pointer %d\n", pointer_space_used);
  fprintf(fp, "data %d\n", data_space_used);
  fprintf(fp, "code %d\n", code_space_used);
  fprintf(fp, "map %d\n", map_space_used);
  fprintf(fp, "cell %d\n", cell_space_used);
  fprintf(fp, "large %d\n", large_space_used);
  fclose(fp);
}


static bool WriteToFile(const char* snapshot_file) {
  FileByteSink file(snapshot_file);
  StartupSerializer ser(&file);
  ser.Serialize();
  return true;
}


static void Serialize() {
  // We have to create one context.  One reason for this is so that the builtins
  // can be loaded from v8natives.js and their addresses can be processed.  This
  // will clear the pending fixups array, which would otherwise contain GC roots
  // that would confuse the serialization/deserialization process.
  v8::Persistent<v8::Context> env = v8::Context::New();
  env.Dispose();
  WriteToFile(FLAG_testing_serialization_file);
}


// Test that the whole heap can be serialized.
TEST(Serialize) {
  Serializer::Enable();
  v8::V8::Initialize();
  Serialize();
}


// Test that heap serialization is non-destructive.
TEST(SerializeTwice) {
  Serializer::Enable();
  v8::V8::Initialize();
  Serialize();
  Serialize();
}


//----------------------------------------------------------------------------
// Tests that the heap can be deserialized.

static void Deserialize() {
  CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
}


static void SanityCheck() {
  v8::HandleScope scope;
#ifdef DEBUG
  HEAP->Verify();
#endif
  CHECK(Isolate::Current()->global()->IsJSObject());
  CHECK(Isolate::Current()->global_context()->IsContext());
  CHECK(HEAP->symbol_table()->IsSymbolTable());
  CHECK(!FACTORY->LookupAsciiSymbol("Empty")->IsFailure());
}


DEPENDENT_TEST(Deserialize, Serialize) {
  // The serialize-deserialize tests only work if the VM is built without
  // serialization.  That doesn't matter.  We don't need to be able to
  // serialize a snapshot in a VM that is booted from a snapshot.
  if (!Snapshot::IsEnabled()) {
    v8::HandleScope scope;
    Deserialize();

    v8::Persistent<v8::Context> env = v8::Context::New();
    env->Enter();

    SanityCheck();
  }
}


DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
  if (!Snapshot::IsEnabled()) {
    v8::HandleScope scope;
    Deserialize();

    v8::Persistent<v8::Context> env = v8::Context::New();
    env->Enter();

    SanityCheck();
  }
}


DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
  if (!Snapshot::IsEnabled()) {
    v8::HandleScope scope;
    Deserialize();

    v8::Persistent<v8::Context> env = v8::Context::New();
    env->Enter();

    const char* c_source = "\"1234\".length";
    v8::Local<v8::String> source = v8::String::New(c_source);
    v8::Local<v8::Script> script = v8::Script::Compile(source);
    CHECK_EQ(4, script->Run()->Int32Value());
  }
}


DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
               SerializeTwice) {
  if (!Snapshot::IsEnabled()) {
    v8::HandleScope scope;
    Deserialize();

    v8::Persistent<v8::Context> env = v8::Context::New();
    env->Enter();

    const char* c_source = "\"1234\".length";
    v8::Local<v8::String> source = v8::String::New(c_source);
    v8::Local<v8::Script> script = v8::Script::Compile(source);
    CHECK_EQ(4, script->Run()->Int32Value());
  }
}


TEST(PartialSerialization) {
  Serializer::Enable();
  v8::V8::Initialize();

  v8::Persistent<v8::Context> env = v8::Context::New();
  ASSERT(!env.IsEmpty());
  env->Enter();
  // Make sure all builtin scripts are cached.
  { HandleScope scope;
    for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
      Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
    }
  }
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);

  Object* raw_foo;
  {
    v8::HandleScope handle_scope;
    v8::Local<v8::String> foo = v8::String::New("foo");
    ASSERT(!foo.IsEmpty());
    raw_foo = *(v8::Utils::OpenHandle(*foo));
  }

  int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
  Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
  OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);

  env->Exit();
  env.Dispose();

  FileByteSink startup_sink(startup_name.start());
  startup_name.Dispose();
  StartupSerializer startup_serializer(&startup_sink);
  startup_serializer.SerializeStrongReferences();

  FileByteSink partial_sink(FLAG_testing_serialization_file);
  PartialSerializer p_ser(&startup_serializer, &partial_sink);
  p_ser.Serialize(&raw_foo);
  startup_serializer.SerializeWeakReferences();
  partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
                              p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
                              p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
                              p_ser.CurrentAllocationAddress(CODE_SPACE),
                              p_ser.CurrentAllocationAddress(MAP_SPACE),
                              p_ser.CurrentAllocationAddress(CELL_SPACE),
                              p_ser.CurrentAllocationAddress(LO_SPACE));
}


static void ReserveSpaceForPartialSnapshot(const char* file_name) {
  int file_name_length = StrLength(file_name) + 10;
  Vector<char> name = Vector<char>::New(file_name_length + 1);
  OS::SNPrintF(name, "%s.size", file_name);
  FILE* fp = OS::FOpen(name.start(), "r");
  name.Dispose();
  int new_size, pointer_size, data_size, code_size, map_size, cell_size;
  int large_size;
#ifdef _MSC_VER
  // Avoid warning about unsafe fscanf from MSVC.
  // Please note that this is only fine if %c and %s are not being used.
#define fscanf fscanf_s
#endif
  CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
  CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
  CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
  CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
  CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
  CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
  CHECK_EQ(1, fscanf(fp, "large %d\n", &large_size));
#ifdef _MSC_VER
#undef fscanf
#endif
  fclose(fp);
  HEAP->ReserveSpace(new_size,
                     pointer_size,
                     data_size,
                     code_size,
                     map_size,
                     cell_size,
                     large_size);
}


DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
  if (!Snapshot::IsEnabled()) {
    int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);

    CHECK(Snapshot::Initialize(startup_name.start()));
    startup_name.Dispose();

    const char* file_name = FLAG_testing_serialization_file;
    ReserveSpaceForPartialSnapshot(file_name);

    int snapshot_size = 0;
    byte* snapshot = ReadBytes(file_name, &snapshot_size);

    Object* root;
    {
      SnapshotByteSource source(snapshot, snapshot_size);
      Deserializer deserializer(&source);
      deserializer.DeserializePartial(&root);
      CHECK(root->IsString());
    }
    v8::HandleScope handle_scope;
    Handle<Object> root_handle(root);

    ReserveSpaceForPartialSnapshot(file_name);

    Object* root2;
    {
      SnapshotByteSource source(snapshot, snapshot_size);
      Deserializer deserializer(&source);
      deserializer.DeserializePartial(&root2);
      CHECK(root2->IsString());
      CHECK(*root_handle == root2);
    }
  }
}


TEST(ContextSerialization) {
  Serializer::Enable();
  v8::V8::Initialize();

  v8::Persistent<v8::Context> env = v8::Context::New();
  ASSERT(!env.IsEmpty());
  env->Enter();
  // Make sure all builtin scripts are cached.
  { HandleScope scope;
    for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
      Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
    }
  }
  // If we don't do this then we end up with a stray root pointing at the
  // context even after we have disposed of env.
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);

  int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
  Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
  OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);

  env->Exit();

  Object* raw_context = *(v8::Utils::OpenHandle(*env));

  env.Dispose();

  FileByteSink startup_sink(startup_name.start());
  startup_name.Dispose();
  StartupSerializer startup_serializer(&startup_sink);
  startup_serializer.SerializeStrongReferences();

  FileByteSink partial_sink(FLAG_testing_serialization_file);
  PartialSerializer p_ser(&startup_serializer, &partial_sink);
  p_ser.Serialize(&raw_context);
  startup_serializer.SerializeWeakReferences();
  partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
                              p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
                              p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
                              p_ser.CurrentAllocationAddress(CODE_SPACE),
                              p_ser.CurrentAllocationAddress(MAP_SPACE),
                              p_ser.CurrentAllocationAddress(CELL_SPACE),
                              p_ser.CurrentAllocationAddress(LO_SPACE));
}


DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
  if (!Snapshot::IsEnabled()) {
    int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
    Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
    OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);

    CHECK(Snapshot::Initialize(startup_name.start()));
    startup_name.Dispose();

    const char* file_name = FLAG_testing_serialization_file;
    ReserveSpaceForPartialSnapshot(file_name);

    int snapshot_size = 0;
    byte* snapshot = ReadBytes(file_name, &snapshot_size);

    Object* root;
    {
      SnapshotByteSource source(snapshot, snapshot_size);
      Deserializer deserializer(&source);
      deserializer.DeserializePartial(&root);
      CHECK(root->IsContext());
    }
    v8::HandleScope handle_scope;
    Handle<Object> root_handle(root);

    ReserveSpaceForPartialSnapshot(file_name);

    Object* root2;
    {
      SnapshotByteSource source(snapshot, snapshot_size);
      Deserializer deserializer(&source);
      deserializer.DeserializePartial(&root2);
      CHECK(root2->IsContext());
      CHECK(*root_handle != root2);
    }
  }
}


TEST(LinearAllocation) {
  v8::V8::Initialize();
  int new_space_max = 512 * KB;
  int paged_space_max = Page::kMaxNonCodeHeapObjectSize;
  int code_space_max = HEAP->code_space()->AreaSize();

  for (int size = 1000; size < 5 * MB; size += size >> 1) {
    size &= ~8;  // Round.
    int new_space_size = (size < new_space_max) ? size : new_space_max;
    int paged_space_size = (size < paged_space_max) ? size : paged_space_max;
    HEAP->ReserveSpace(
        new_space_size,
        paged_space_size,  // Old pointer space.
        paged_space_size,  // Old data space.
        HEAP->code_space()->RoundSizeDownToObjectAlignment(code_space_max),
        HEAP->map_space()->RoundSizeDownToObjectAlignment(paged_space_size),
        HEAP->cell_space()->RoundSizeDownToObjectAlignment(paged_space_size),
        size);             // Large object space.
    LinearAllocationScope linear_allocation_scope;
    const int kSmallFixedArrayLength = 4;
    const int kSmallFixedArraySize =
        FixedArray::kHeaderSize + kSmallFixedArrayLength * kPointerSize;
    const int kSmallStringLength = 16;
    const int kSmallStringSize =
        (SeqAsciiString::kHeaderSize + kSmallStringLength +
        kObjectAlignmentMask) & ~kObjectAlignmentMask;
    const int kMapSize = Map::kSize;

    Object* new_last = NULL;
    for (int i = 0;
         i + kSmallFixedArraySize <= new_space_size;
         i += kSmallFixedArraySize) {
      Object* obj =
          HEAP->AllocateFixedArray(kSmallFixedArrayLength)->ToObjectChecked();
      if (new_last != NULL) {
        CHECK(reinterpret_cast<char*>(obj) ==
              reinterpret_cast<char*>(new_last) + kSmallFixedArraySize);
      }
      new_last = obj;
    }

    Object* pointer_last = NULL;
    for (int i = 0;
         i + kSmallFixedArraySize <= paged_space_size;
         i += kSmallFixedArraySize) {
      Object* obj = HEAP->AllocateFixedArray(kSmallFixedArrayLength,
                                             TENURED)->ToObjectChecked();
      int old_page_fullness = i % Page::kPageSize;
      int page_fullness = (i + kSmallFixedArraySize) % Page::kPageSize;
      if (page_fullness < old_page_fullness ||
          page_fullness > HEAP->old_pointer_space()->AreaSize()) {
        i = RoundUp(i, Page::kPageSize);
        pointer_last = NULL;
      }
      if (pointer_last != NULL) {
        CHECK(reinterpret_cast<char*>(obj) ==
              reinterpret_cast<char*>(pointer_last) + kSmallFixedArraySize);
      }
      pointer_last = obj;
    }

    Object* data_last = NULL;
    for (int i = 0;
         i + kSmallStringSize <= paged_space_size;
         i += kSmallStringSize) {
      Object* obj = HEAP->AllocateRawAsciiString(kSmallStringLength,
                                                 TENURED)->ToObjectChecked();
      int old_page_fullness = i % Page::kPageSize;
      int page_fullness = (i + kSmallStringSize) % Page::kPageSize;
      if (page_fullness < old_page_fullness ||
          page_fullness > HEAP->old_data_space()->AreaSize()) {
        i = RoundUp(i, Page::kPageSize);
        data_last = NULL;
      }
      if (data_last != NULL) {
        CHECK(reinterpret_cast<char*>(obj) ==
              reinterpret_cast<char*>(data_last) + kSmallStringSize);
      }
      data_last = obj;
    }

    Object* map_last = NULL;
    for (int i = 0; i + kMapSize <= paged_space_size; i += kMapSize) {
      Object* obj = HEAP->AllocateMap(JS_OBJECT_TYPE,
                                      42 * kPointerSize)->ToObjectChecked();
      int old_page_fullness = i % Page::kPageSize;
      int page_fullness = (i + kMapSize) % Page::kPageSize;
      if (page_fullness < old_page_fullness ||
          page_fullness > HEAP->map_space()->AreaSize()) {
        i = RoundUp(i, Page::kPageSize);
        map_last = NULL;
      }
      if (map_last != NULL) {
        CHECK(reinterpret_cast<char*>(obj) ==
              reinterpret_cast<char*>(map_last) + kMapSize);
      }
      map_last = obj;
    }

    if (size > Page::kMaxNonCodeHeapObjectSize) {
      // Support for reserving space in large object space is not there yet,
      // but using an always-allocate scope is fine for now.
      AlwaysAllocateScope always;
      int large_object_array_length =
          (size - FixedArray::kHeaderSize) / kPointerSize;
      Object* obj = HEAP->AllocateFixedArray(large_object_array_length,
                                             TENURED)->ToObjectChecked();
      CHECK(!obj->IsFailure());
    }
  }
}


TEST(TestThatAlwaysSucceeds) {
}


TEST(TestThatAlwaysFails) {
  bool ArtificialFailure = false;
  CHECK(ArtificialFailure);
}


DEPENDENT_TEST(DependentTestThatAlwaysFails, TestThatAlwaysSucceeds) {
  bool ArtificialFailure2 = false;
  CHECK(ArtificialFailure2);
}
