// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdlib.h>
#include <utility>

#include "src/v8.h"

#include "src/accessors.h"
#include "src/api.h"
#include "src/compilation-cache.h"
#include "src/execution.h"
#include "src/factory.h"
#include "src/field-type.h"
#include "src/global-handles.h"
#include "src/heap/incremental-marking.h"
#include "src/heap/spaces.h"
#include "src/ic/ic.h"
#include "src/layout-descriptor.h"
#include "src/macro-assembler.h"
#include "src/objects-inl.h"
#include "src/property.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"

namespace v8 {
namespace internal {
namespace test_unboxed_doubles {

#if V8_DOUBLE_FIELDS_UNBOXING


//
// Helper functions.
//


static void InitializeVerifiedMapDescriptors(
    Map* map, DescriptorArray* descriptors,
    LayoutDescriptor* layout_descriptor) {
  map->InitializeDescriptors(descriptors, layout_descriptor);
  CHECK(layout_descriptor->IsConsistentWithMap(map, true));
}


static Handle<String> MakeString(const char* str) {
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();
  return factory->InternalizeUtf8String(str);
}


static Handle<String> MakeName(const char* str, int suffix) {
  EmbeddedVector<char, 128> buffer;
  SNPrintF(buffer, "%s%d", str, suffix);
  return MakeString(buffer.start());
}


Handle<JSObject> GetObject(const char* name) {
  return Handle<JSObject>::cast(
      v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(
          CcTest::global()
              ->Get(v8::Isolate::GetCurrent()->GetCurrentContext(),
                    v8_str(name))
              .ToLocalChecked())));
}


static double GetDoubleFieldValue(JSObject* obj, FieldIndex field_index) {
  if (obj->IsUnboxedDoubleField(field_index)) {
    return obj->RawFastDoublePropertyAt(field_index);
  } else {
    Object* value = obj->RawFastPropertyAt(field_index);
    CHECK(value->IsMutableHeapNumber());
    return HeapNumber::cast(value)->value();
  }
}

void WriteToField(JSObject* object, int descriptor, Object* value) {
  DescriptorArray* descriptors = object->map()->instance_descriptors();
  PropertyDetails details = descriptors->GetDetails(descriptor);
  object->WriteToField(descriptor, details, value);
}

const int kNumberOfBits = 32;

enum TestPropertyKind {
  PROP_ACCESSOR_INFO,
  PROP_SMI,
  PROP_DOUBLE,
  PROP_TAGGED,
  PROP_KIND_NUMBER
};

static Representation representations[PROP_KIND_NUMBER] = {
    Representation::None(), Representation::Smi(), Representation::Double(),
    Representation::Tagged()};


static Handle<DescriptorArray> CreateDescriptorArray(Isolate* isolate,
                                                     TestPropertyKind* props,
                                                     int kPropsCount) {
  Factory* factory = isolate->factory();

  Handle<DescriptorArray> descriptors =
      DescriptorArray::Allocate(isolate, 0, kPropsCount);

  int next_field_offset = 0;
  for (int i = 0; i < kPropsCount; i++) {
    EmbeddedVector<char, 64> buffer;
    SNPrintF(buffer, "prop%d", i);
    Handle<String> name = factory->InternalizeUtf8String(buffer.start());

    TestPropertyKind kind = props[i];

    Descriptor d;
    if (kind == PROP_ACCESSOR_INFO) {
      Handle<AccessorInfo> info =
          Accessors::MakeAccessor(isolate, name, nullptr, nullptr);
      d = Descriptor::AccessorConstant(name, info, NONE);

    } else {
      d = Descriptor::DataField(name, next_field_offset, NONE,
                                representations[kind]);
    }
    descriptors->Append(&d);
    PropertyDetails details = d.GetDetails();
    if (details.location() == kField) {
      next_field_offset += details.field_width_in_words();
    }
  }
  return descriptors;
}


TEST(LayoutDescriptorBasicFast) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  LayoutDescriptor* layout_desc = LayoutDescriptor::FastPointerLayout();

  CHECK(!layout_desc->IsSlowLayout());
  CHECK(layout_desc->IsFastPointerLayout());
  CHECK_EQ(kSmiValueSize, layout_desc->capacity());

  for (int i = 0; i < kSmiValueSize + 13; i++) {
    CHECK(layout_desc->IsTagged(i));
  }
  CHECK(layout_desc->IsTagged(-1));
  CHECK(layout_desc->IsTagged(-12347));
  CHECK(layout_desc->IsTagged(15635));
  CHECK(layout_desc->IsFastPointerLayout());

  for (int i = 0; i < kSmiValueSize; i++) {
    layout_desc = layout_desc->SetTaggedForTesting(i, false);
    CHECK(!layout_desc->IsTagged(i));
    layout_desc = layout_desc->SetTaggedForTesting(i, true);
    CHECK(layout_desc->IsTagged(i));
  }
  CHECK(layout_desc->IsFastPointerLayout());

  int sequence_length;
  CHECK_EQ(true, layout_desc->IsTagged(0, std::numeric_limits<int>::max(),
                                       &sequence_length));
  CHECK_EQ(std::numeric_limits<int>::max(), sequence_length);

  CHECK(layout_desc->IsTagged(0, 7, &sequence_length));
  CHECK_EQ(7, sequence_length);
}


TEST(LayoutDescriptorBasicSlow) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    // All properties tagged.
    props[i] = PROP_TAGGED;
  }

  {
    Handle<DescriptorArray> descriptors =
        CreateDescriptorArray(isolate, props, kPropsCount);

    Handle<Map> map = Map::Create(isolate, kPropsCount);

    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    CHECK_EQ(kSmiValueSize, layout_descriptor->capacity());
    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);
  }

  props[0] = PROP_DOUBLE;
  props[kPropsCount - 1] = PROP_DOUBLE;

  Handle<DescriptorArray> descriptors =
      CreateDescriptorArray(isolate, props, kPropsCount);

  {
    int inobject_properties = kPropsCount - 1;
    Handle<Map> map = Map::Create(isolate, inobject_properties);

    // Should be fast as the only double property is the first one.
    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    CHECK(!layout_descriptor->IsSlowLayout());
    CHECK(!layout_descriptor->IsFastPointerLayout());

    CHECK(!layout_descriptor->IsTagged(0));
    for (int i = 1; i < kPropsCount; i++) {
      CHECK(layout_descriptor->IsTagged(i));
    }
    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);
  }

  {
    int inobject_properties = kPropsCount;
    Handle<Map> map = Map::Create(isolate, inobject_properties);

    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    CHECK(layout_descriptor->IsSlowLayout());
    CHECK(!layout_descriptor->IsFastPointerLayout());
    CHECK_GT(layout_descriptor->capacity(), kSmiValueSize);

    CHECK(!layout_descriptor->IsTagged(0));
    CHECK(!layout_descriptor->IsTagged(kPropsCount - 1));
    for (int i = 1; i < kPropsCount - 1; i++) {
      CHECK(layout_descriptor->IsTagged(i));
    }

    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);

    // Here we have truly slow layout descriptor, so play with the bits.
    CHECK(layout_descriptor->IsTagged(-1));
    CHECK(layout_descriptor->IsTagged(-12347));
    CHECK(layout_descriptor->IsTagged(15635));

    LayoutDescriptor* layout_desc = *layout_descriptor;
    // Play with the bits but leave it in consistent state with map at the end.
    for (int i = 1; i < kPropsCount - 1; i++) {
      layout_desc = layout_desc->SetTaggedForTesting(i, false);
      CHECK(!layout_desc->IsTagged(i));
      layout_desc = layout_desc->SetTaggedForTesting(i, true);
      CHECK(layout_desc->IsTagged(i));
    }
    CHECK(layout_desc->IsSlowLayout());
    CHECK(!layout_desc->IsFastPointerLayout());
    CHECK(layout_descriptor->IsConsistentWithMap(*map, true));
  }
}


static void TestLayoutDescriptorQueries(int layout_descriptor_length,
                                        int* bit_flip_positions,
                                        int max_sequence_length) {
  Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::NewForTesting(
      CcTest::i_isolate(), layout_descriptor_length);
  layout_descriptor_length = layout_descriptor->capacity();
  LayoutDescriptor* layout_desc = *layout_descriptor;

  {
    // Fill in the layout descriptor.
    int cur_bit_flip_index = 0;
    bool tagged = true;
    for (int i = 0; i < layout_descriptor_length; i++) {
      if (i == bit_flip_positions[cur_bit_flip_index]) {
        tagged = !tagged;
        ++cur_bit_flip_index;
        CHECK(i < bit_flip_positions[cur_bit_flip_index]);  // check test data
      }
      layout_desc = layout_desc->SetTaggedForTesting(i, tagged);
    }
  }

  if (layout_desc->IsFastPointerLayout()) {
    return;
  }

  {
    // Check queries.
    int cur_bit_flip_index = 0;
    bool tagged = true;
    for (int i = 0; i < layout_descriptor_length; i++) {
      if (i == bit_flip_positions[cur_bit_flip_index]) {
        tagged = !tagged;
        ++cur_bit_flip_index;
      }
      CHECK_EQ(tagged, layout_desc->IsTagged(i));

      int next_bit_flip_position = bit_flip_positions[cur_bit_flip_index];
      int expected_sequence_length;
      if (next_bit_flip_position < layout_desc->capacity()) {
        expected_sequence_length = next_bit_flip_position - i;
      } else {
        expected_sequence_length = tagged ? std::numeric_limits<int>::max()
                                          : (layout_desc->capacity() - i);
      }
      expected_sequence_length =
          Min(expected_sequence_length, max_sequence_length);
      int sequence_length;
      CHECK_EQ(tagged,
               layout_desc->IsTagged(i, max_sequence_length, &sequence_length));
      CHECK_GT(sequence_length, 0);

      CHECK_EQ(expected_sequence_length, sequence_length);
    }

    int sequence_length;
    CHECK_EQ(true,
             layout_desc->IsTagged(layout_descriptor_length,
                                   max_sequence_length, &sequence_length));
    CHECK_EQ(max_sequence_length, sequence_length);
  }
}


static void TestLayoutDescriptorQueriesFast(int max_sequence_length) {
  {
    LayoutDescriptor* layout_desc = LayoutDescriptor::FastPointerLayout();
    int sequence_length;
    for (int i = 0; i < kNumberOfBits; i++) {
      CHECK_EQ(true,
               layout_desc->IsTagged(i, max_sequence_length, &sequence_length));
      CHECK_GT(sequence_length, 0);
      CHECK_EQ(max_sequence_length, sequence_length);
    }
  }

  {
    int bit_flip_positions[] = {1000};
    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[] = {0, 1000};
    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[kNumberOfBits + 1];
    for (int i = 0; i <= kNumberOfBits; i++) {
      bit_flip_positions[i] = i;
    }
    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[] = {3, 7, 8, 10, 15, 21, 30, 1000};
    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[] = {0,  1,  2,  3,  5,  7,  9,
                                12, 15, 18, 22, 26, 29, 1000};
    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
                                max_sequence_length);
  }
}


TEST(LayoutDescriptorQueriesFastLimited7) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestLayoutDescriptorQueriesFast(7);
}


TEST(LayoutDescriptorQueriesFastLimited13) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestLayoutDescriptorQueriesFast(13);
}


TEST(LayoutDescriptorQueriesFastUnlimited) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestLayoutDescriptorQueriesFast(std::numeric_limits<int>::max());
}


static void TestLayoutDescriptorQueriesSlow(int max_sequence_length) {
  {
    int bit_flip_positions[] = {10000};
    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[] = {0, 10000};
    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[kMaxNumberOfDescriptors + 1];
    for (int i = 0; i < kMaxNumberOfDescriptors; i++) {
      bit_flip_positions[i] = i;
    }
    bit_flip_positions[kMaxNumberOfDescriptors] = 10000;
    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[] = {3,  7,  8,  10, 15,  21,   30,
                                37, 54, 80, 99, 383, 10000};
    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[] = {0,   10,  20,  30,  50,  70,  90,
                                120, 150, 180, 220, 260, 290, 10000};
    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[kMaxNumberOfDescriptors + 1];
    int cur = 0;
    for (int i = 0; i < kMaxNumberOfDescriptors; i++) {
      bit_flip_positions[i] = cur;
      cur = (cur + 1) * 2;
    }
    CHECK_LT(cur, 10000);
    bit_flip_positions[kMaxNumberOfDescriptors] = 10000;
    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
                                max_sequence_length);
  }

  {
    int bit_flip_positions[kMaxNumberOfDescriptors + 1];
    int cur = 3;
    for (int i = 0; i < kMaxNumberOfDescriptors; i++) {
      bit_flip_positions[i] = cur;
      cur = (cur + 1) * 2;
    }
    CHECK_LT(cur, 10000);
    bit_flip_positions[kMaxNumberOfDescriptors] = 10000;
    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
                                max_sequence_length);
  }
}


TEST(LayoutDescriptorQueriesSlowLimited7) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestLayoutDescriptorQueriesSlow(7);
}


TEST(LayoutDescriptorQueriesSlowLimited13) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestLayoutDescriptorQueriesSlow(13);
}


TEST(LayoutDescriptorQueriesSlowLimited42) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestLayoutDescriptorQueriesSlow(42);
}


TEST(LayoutDescriptorQueriesSlowUnlimited) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestLayoutDescriptorQueriesSlow(std::numeric_limits<int>::max());
}


TEST(LayoutDescriptorCreateNewFast) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  TestPropertyKind props[] = {
      PROP_ACCESSOR_INFO,
      PROP_TAGGED,  // field #0
      PROP_ACCESSOR_INFO,
      PROP_DOUBLE,  // field #1
      PROP_ACCESSOR_INFO,
      PROP_TAGGED,  // field #2
      PROP_ACCESSOR_INFO,
  };
  const int kPropsCount = arraysize(props);

  Handle<DescriptorArray> descriptors =
      CreateDescriptorArray(isolate, props, kPropsCount);

  {
    Handle<Map> map = Map::Create(isolate, 0);
    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);
  }

  {
    Handle<Map> map = Map::Create(isolate, 1);
    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);
  }

  {
    Handle<Map> map = Map::Create(isolate, 2);
    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    CHECK(!layout_descriptor->IsSlowLayout());
    CHECK(layout_descriptor->IsTagged(0));
    CHECK(!layout_descriptor->IsTagged(1));
    CHECK(layout_descriptor->IsTagged(2));
    CHECK(layout_descriptor->IsTagged(125));
    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);
  }
}


TEST(LayoutDescriptorCreateNewSlow) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    props[i] = static_cast<TestPropertyKind>(i % PROP_KIND_NUMBER);
  }

  Handle<DescriptorArray> descriptors =
      CreateDescriptorArray(isolate, props, kPropsCount);

  {
    Handle<Map> map = Map::Create(isolate, 0);
    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);
  }

  {
    Handle<Map> map = Map::Create(isolate, 1);
    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);
  }

  {
    Handle<Map> map = Map::Create(isolate, 2);
    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    CHECK(!layout_descriptor->IsSlowLayout());
    CHECK(layout_descriptor->IsTagged(0));
    CHECK(!layout_descriptor->IsTagged(1));
    CHECK(layout_descriptor->IsTagged(2));
    CHECK(layout_descriptor->IsTagged(125));
    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);
  }

  {
    int inobject_properties = kPropsCount / 2;
    Handle<Map> map = Map::Create(isolate, inobject_properties);
    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
    CHECK(layout_descriptor->IsSlowLayout());
    for (int i = 0; i < inobject_properties; i++) {
      // PROP_DOUBLE has index 1 among DATA properties.
      const bool tagged = (i % (PROP_KIND_NUMBER - 1)) != 1;
      CHECK_EQ(tagged, layout_descriptor->IsTagged(i));
    }
    // Every property after inobject_properties must be tagged.
    for (int i = inobject_properties; i < kPropsCount; i++) {
      CHECK(layout_descriptor->IsTagged(i));
    }
    InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);

    // Now test LayoutDescriptor::cast_gc_safe().
    Handle<LayoutDescriptor> layout_descriptor_copy =
        LayoutDescriptor::New(map, descriptors, kPropsCount);

    LayoutDescriptor* layout_desc = *layout_descriptor;
    CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
    CHECK_EQ(layout_desc, LayoutDescriptor::cast_gc_safe(layout_desc));
    CHECK(layout_desc->IsSlowLayout());
    // Now make it look like a forwarding pointer to layout_descriptor_copy.
    MapWord map_word = layout_desc->map_word();
    CHECK(!map_word.IsForwardingAddress());
    layout_desc->set_map_word(
        MapWord::FromForwardingAddress(*layout_descriptor_copy));
    CHECK(layout_desc->map_word().IsForwardingAddress());
    CHECK_EQ(layout_desc, LayoutDescriptor::cast_gc_safe(layout_desc));

    // Restore it back.
    layout_desc->set_map_word(map_word);
    CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
  }
}


static Handle<LayoutDescriptor> TestLayoutDescriptorAppend(
    Isolate* isolate, int inobject_properties, TestPropertyKind* props,
    int kPropsCount) {
  Factory* factory = isolate->factory();

  Handle<DescriptorArray> descriptors =
      DescriptorArray::Allocate(isolate, 0, kPropsCount);

  Handle<Map> map = Map::Create(isolate, inobject_properties);
  map->InitializeDescriptors(*descriptors,
                             LayoutDescriptor::FastPointerLayout());

  int next_field_offset = 0;
  for (int i = 0; i < kPropsCount; i++) {
    EmbeddedVector<char, 64> buffer;
    SNPrintF(buffer, "prop%d", i);
    Handle<String> name = factory->InternalizeUtf8String(buffer.start());

    Handle<LayoutDescriptor> layout_descriptor;
    TestPropertyKind kind = props[i];
    Descriptor d;
    if (kind == PROP_ACCESSOR_INFO) {
      Handle<AccessorInfo> info =
          Accessors::MakeAccessor(isolate, name, nullptr, nullptr);
      d = Descriptor::AccessorConstant(name, info, NONE);

    } else {
      d = Descriptor::DataField(name, next_field_offset, NONE,
                                representations[kind]);
    }
    PropertyDetails details = d.GetDetails();
    layout_descriptor = LayoutDescriptor::ShareAppend(map, details);
    descriptors->Append(&d);
    if (details.location() == kField) {
      int field_width_in_words = details.field_width_in_words();
      next_field_offset += field_width_in_words;

      int field_index = details.field_index();
      bool is_inobject = field_index < map->GetInObjectProperties();
      for (int bit = 0; bit < field_width_in_words; bit++) {
        CHECK_EQ(is_inobject && (kind == PROP_DOUBLE),
                 !layout_descriptor->IsTagged(field_index + bit));
      }
      CHECK(layout_descriptor->IsTagged(next_field_offset));
    }
    map->InitializeDescriptors(*descriptors, *layout_descriptor);
  }
  Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate);
  CHECK(layout_descriptor->IsConsistentWithMap(*map, true));
  return layout_descriptor;
}


TEST(LayoutDescriptorAppend) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    props[i] = static_cast<TestPropertyKind>(i % PROP_KIND_NUMBER);
  }

  layout_descriptor =
      TestLayoutDescriptorAppend(isolate, 0, props, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor =
      TestLayoutDescriptorAppend(isolate, 13, props, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor =
      TestLayoutDescriptorAppend(isolate, kSmiValueSize, props, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize * 2,
                                                 props, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());

  layout_descriptor =
      TestLayoutDescriptorAppend(isolate, kPropsCount, props, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());
}


TEST(LayoutDescriptorAppendAllDoubles) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    props[i] = PROP_DOUBLE;
  }

  layout_descriptor =
      TestLayoutDescriptorAppend(isolate, 0, props, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor =
      TestLayoutDescriptorAppend(isolate, 13, props, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor =
      TestLayoutDescriptorAppend(isolate, kSmiValueSize, props, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize + 1,
                                                 props, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize * 2,
                                                 props, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());

  layout_descriptor =
      TestLayoutDescriptorAppend(isolate, kPropsCount, props, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());

  {
    // Ensure layout descriptor switches into slow mode at the right moment.
    layout_descriptor =
        TestLayoutDescriptorAppend(isolate, kPropsCount, props, kSmiValueSize);
    CHECK(!layout_descriptor->IsSlowLayout());

    layout_descriptor = TestLayoutDescriptorAppend(isolate, kPropsCount, props,
                                                   kSmiValueSize + 1);
    CHECK(layout_descriptor->IsSlowLayout());
  }
}


static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull(
    Isolate* isolate, int inobject_properties,
    Handle<DescriptorArray> descriptors, int number_of_descriptors) {
  Handle<Map> initial_map = Map::Create(isolate, inobject_properties);

  Handle<LayoutDescriptor> full_layout_descriptor = LayoutDescriptor::New(
      initial_map, descriptors, descriptors->number_of_descriptors());

  int nof = 0;
  bool switched_to_slow_mode = false;

  // This method calls LayoutDescriptor::AppendIfFastOrUseFull() internally
  // and does all the required map-descriptors related book keeping.
  Handle<Map> last_map = Map::AddMissingTransitionsForTesting(
      initial_map, descriptors, full_layout_descriptor);

  // Follow back pointers to construct a sequence of maps from |map|
  // to |last_map|.
  int descriptors_length = descriptors->number_of_descriptors();
  std::vector<Handle<Map>> maps(descriptors_length);
  {
    CHECK(last_map->is_stable());
    Map* map = *last_map;
    for (int i = 0; i < descriptors_length; i++) {
      maps[descriptors_length - 1 - i] = handle(map, isolate);
      Object* maybe_map = map->GetBackPointer();
      CHECK(maybe_map->IsMap());
      map = Map::cast(maybe_map);
      CHECK(!map->is_stable());
    }
    CHECK_EQ(1, maps[0]->NumberOfOwnDescriptors());
  }

  Handle<Map> map;
  // Now check layout descriptors of all intermediate maps.
  for (int i = 0; i < number_of_descriptors; i++) {
    PropertyDetails details = descriptors->GetDetails(i);
    map = maps[i];
    LayoutDescriptor* layout_desc = map->layout_descriptor();

    if (layout_desc->IsSlowLayout()) {
      switched_to_slow_mode = true;
      CHECK_EQ(*full_layout_descriptor, layout_desc);
    } else {
      CHECK(!switched_to_slow_mode);
      if (details.location() == kField) {
        nof++;
        int field_index = details.field_index();
        int field_width_in_words = details.field_width_in_words();

        bool is_inobject = field_index < map->GetInObjectProperties();
        for (int bit = 0; bit < field_width_in_words; bit++) {
          CHECK_EQ(is_inobject && details.representation().IsDouble(),
                   !layout_desc->IsTagged(field_index + bit));
        }
        CHECK(layout_desc->IsTagged(field_index + field_width_in_words));
      }
    }
    CHECK(map->layout_descriptor()->IsConsistentWithMap(*map));
  }

  Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(),
                                             isolate);
  CHECK(layout_descriptor->IsConsistentWithMap(*map));
  return layout_descriptor;
}


TEST(LayoutDescriptorAppendIfFastOrUseFull) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    props[i] = static_cast<TestPropertyKind>(i % PROP_KIND_NUMBER);
  }
  Handle<DescriptorArray> descriptors =
      CreateDescriptorArray(isolate, props, kPropsCount);

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, 0, descriptors, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, 13, descriptors, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, kSmiValueSize, descriptors, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, kSmiValueSize * 2, descriptors, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, kPropsCount, descriptors, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());
}


TEST(LayoutDescriptorAppendIfFastOrUseFullAllDoubles) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    props[i] = PROP_DOUBLE;
  }
  Handle<DescriptorArray> descriptors =
      CreateDescriptorArray(isolate, props, kPropsCount);

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, 0, descriptors, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, 13, descriptors, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, kSmiValueSize, descriptors, kPropsCount);
  CHECK(!layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, kSmiValueSize + 1, descriptors, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, kSmiValueSize * 2, descriptors, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());

  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
      isolate, kPropsCount, descriptors, kPropsCount);
  CHECK(layout_descriptor->IsSlowLayout());

  {
    // Ensure layout descriptor switches into slow mode at the right moment.
    layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
        isolate, kPropsCount, descriptors, kSmiValueSize);
    CHECK(!layout_descriptor->IsSlowLayout());

    layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
        isolate, kPropsCount, descriptors, kSmiValueSize + 1);
    CHECK(layout_descriptor->IsSlowLayout());
  }
}


TEST(Regress436816) {
  ManualGCScope manual_gc_scope;
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();
  v8::HandleScope scope(CcTest::isolate());

  // Force a GC to free up space before we allocate objects whose
  // mid-test states would fail heap verification.
  CcTest::CollectAllGarbage();

  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    props[i] = PROP_DOUBLE;
  }
  Handle<DescriptorArray> descriptors =
      CreateDescriptorArray(isolate, props, kPropsCount);

  Handle<Map> map = Map::Create(isolate, kPropsCount);
  Handle<LayoutDescriptor> layout_descriptor =
      LayoutDescriptor::New(map, descriptors, kPropsCount);
  map->InitializeDescriptors(*descriptors, *layout_descriptor);

  Handle<JSObject> object = factory->NewJSObjectFromMap(map, TENURED);

  Address fake_address = reinterpret_cast<Address>(~kHeapObjectTagMask);
  HeapObject* fake_object = HeapObject::FromAddress(fake_address);
  CHECK(fake_object->IsHeapObject());

  uint64_t boom_value = bit_cast<uint64_t>(fake_object);
  for (int i = 0; i < kPropsCount; i++) {
    FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    CHECK(map->IsUnboxedDoubleField(index));
    object->RawFastDoublePropertyAsBitsAtPut(index, boom_value);
  }
  CHECK(object->HasFastProperties());
  CHECK(!object->map()->HasFastPointerLayout());

  Handle<Map> normalized_map =
      Map::Normalize(map, KEEP_INOBJECT_PROPERTIES, "testing");
  JSObject::MigrateToMap(object, normalized_map);
  CHECK(!object->HasFastProperties());
  CHECK(object->map()->HasFastPointerLayout());

  // Trigger GCs and heap verification.
  CcTest::CollectAllGarbage();
}


TEST(DescriptorArrayTrimming) {
  ManualGCScope manual_gc_scope;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();

  const int kFieldCount = 128;
  const int kSplitFieldIndex = 32;
  const int kTrimmedLayoutDescriptorLength = 64;

  Handle<FieldType> any_type = FieldType::Any(isolate);
  Handle<Map> map = Map::Create(isolate, kFieldCount);
  for (int i = 0; i < kSplitFieldIndex; i++) {
    map = Map::CopyWithField(map, MakeName("prop", i), any_type, NONE, kMutable,
                             Representation::Smi(), INSERT_TRANSITION)
              .ToHandleChecked();
  }
  map =
      Map::CopyWithField(map, MakeName("dbl", kSplitFieldIndex), any_type, NONE,
                         kMutable, Representation::Double(), INSERT_TRANSITION)
          .ToHandleChecked();
  CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true));
  CHECK(map->layout_descriptor()->IsSlowLayout());
  CHECK(map->owns_descriptors());
  CHECK_EQ(8, map->layout_descriptor()->length());

  {
    // Add transitions to double fields.
    v8::HandleScope scope(CcTest::isolate());

    Handle<Map> tmp_map = map;
    for (int i = kSplitFieldIndex + 1; i < kFieldCount; i++) {
      tmp_map = Map::CopyWithField(tmp_map, MakeName("dbl", i), any_type, NONE,
                                   kMutable, Representation::Double(),
                                   INSERT_TRANSITION)
                    .ToHandleChecked();
      CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true));
    }
    // Check that descriptors are shared.
    CHECK(tmp_map->owns_descriptors());
    CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors());
    CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor());
  }
  CHECK(map->layout_descriptor()->IsSlowLayout());
  CHECK_EQ(16, map->layout_descriptor()->length());

  // The unused tail of the layout descriptor is now "durty" because of sharing.
  CHECK(map->layout_descriptor()->IsConsistentWithMap(*map));
  for (int i = kSplitFieldIndex + 1; i < kTrimmedLayoutDescriptorLength; i++) {
    CHECK(!map->layout_descriptor()->IsTagged(i));
  }
  CHECK_LT(map->NumberOfOwnDescriptors(),
           map->instance_descriptors()->number_of_descriptors());

  // Call GC that should trim both |map|'s descriptor array and layout
  // descriptor.
  CcTest::CollectAllGarbage();

  // The unused tail of the layout descriptor is now "clean" again.
  CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true));
  CHECK(map->owns_descriptors());
  CHECK_EQ(map->NumberOfOwnDescriptors(),
           map->instance_descriptors()->number_of_descriptors());
  CHECK(map->layout_descriptor()->IsSlowLayout());
  CHECK_EQ(8, map->layout_descriptor()->length());

  {
    // Add transitions to tagged fields.
    v8::HandleScope scope(CcTest::isolate());

    Handle<Map> tmp_map = map;
    for (int i = kSplitFieldIndex + 1; i < kFieldCount - 1; i++) {
      tmp_map = Map::CopyWithField(tmp_map, MakeName("tagged", i), any_type,
                                   NONE, kMutable, Representation::Tagged(),
                                   INSERT_TRANSITION)
                    .ToHandleChecked();
      CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true));
    }
    tmp_map =
        Map::CopyWithField(tmp_map, MakeString("dbl"), any_type, NONE, kMutable,
                           Representation::Double(), INSERT_TRANSITION)
            .ToHandleChecked();
    CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true));
    // Check that descriptors are shared.
    CHECK(tmp_map->owns_descriptors());
    CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors());
  }
  CHECK(map->layout_descriptor()->IsSlowLayout());
}


TEST(DoScavenge) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();

  // The plan: create |obj| with double field in new space, do scanvenge so
  // that |obj| is moved to old space, construct a double value that looks like
  // a pointer to "from space" pointer. Do scavenge one more time and ensure
  // that it didn't crash or corrupt the double value stored in the object.

  Handle<FieldType> any_type = FieldType::Any(isolate);
  Handle<Map> map = Map::Create(isolate, 10);
  map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, kMutable,
                           Representation::Double(), INSERT_TRANSITION)
            .ToHandleChecked();

  // Create object in new space.
  Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED);

  Handle<HeapNumber> heap_number = factory->NewHeapNumber(42.5);
  WriteToField(*obj, 0, *heap_number);

  {
    // Ensure the object is properly set up.
    FieldIndex field_index = FieldIndex::ForDescriptor(*map, 0);
    CHECK(field_index.is_inobject() && field_index.is_double());
    CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index));
    CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index));
  }
  CHECK(isolate->heap()->new_space()->Contains(*obj));

  // Do scavenge so that |obj| is moved to survivor space.
  CcTest::CollectGarbage(i::NEW_SPACE);

  // Create temp object in the new space.
  Handle<JSArray> temp = factory->NewJSArray(0, PACKED_ELEMENTS);
  CHECK(isolate->heap()->new_space()->Contains(*temp));

  // Construct a double value that looks like a pointer to the new space object
  // and store it into the obj.
  Address fake_object = reinterpret_cast<Address>(*temp) + kPointerSize;
  double boom_value = bit_cast<double>(fake_object);

  FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0);
  Handle<HeapNumber> boom_number = factory->NewHeapNumber(boom_value, MUTABLE);
  obj->FastPropertyAtPut(field_index, *boom_number);

  // Now |obj| moves to old gen and it has a double field that looks like
  // a pointer to a from semi-space.
  CcTest::CollectGarbage(i::NEW_SPACE);

  CHECK(isolate->heap()->old_space()->Contains(*obj));

  CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index));
}


TEST(DoScavengeWithIncrementalWriteBarrier) {
  if (FLAG_never_compact || !FLAG_incremental_marking) return;
  ManualGCScope manual_gc_scope;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();
  Heap* heap = CcTest::heap();
  PagedSpace* old_space = heap->old_space();

  // The plan: create |obj_value| in old space and ensure that it is allocated
  // on evacuation candidate page, create |obj| with double and tagged fields
  // in new space and write |obj_value| to tagged field of |obj|, do two
  // scavenges to promote |obj| to old space, a GC in old space and ensure that
  // the tagged value was properly updated after candidates evacuation.

  Handle<FieldType> any_type = FieldType::Any(isolate);
  Handle<Map> map = Map::Create(isolate, 10);
  map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, kMutable,
                           Representation::Double(), INSERT_TRANSITION)
            .ToHandleChecked();
  map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, kMutable,
                           Representation::Tagged(), INSERT_TRANSITION)
            .ToHandleChecked();

  // Create |obj_value| in old space.
  Handle<HeapObject> obj_value;
  Page* ec_page;
  {
    AlwaysAllocateScope always_allocate(isolate);
    // Make sure |obj_value| is placed on an old-space evacuation candidate.
    heap::SimulateFullSpace(old_space);
    obj_value = factory->NewJSArray(32 * KB, HOLEY_ELEMENTS, TENURED);
    ec_page = Page::FromAddress(obj_value->address());
  }

  // Create object in new space.
  Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED);

  Handle<HeapNumber> heap_number = factory->NewHeapNumber(42.5);
  WriteToField(*obj, 0, *heap_number);
  WriteToField(*obj, 1, *obj_value);

  {
    // Ensure the object is properly set up.
    FieldIndex field_index = FieldIndex::ForDescriptor(*map, 0);
    CHECK(field_index.is_inobject() && field_index.is_double());
    CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index));
    CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index));

    field_index = FieldIndex::ForDescriptor(*map, 1);
    CHECK(field_index.is_inobject() && !field_index.is_double());
    CHECK(!map->IsUnboxedDoubleField(field_index));
  }
  CHECK(isolate->heap()->new_space()->Contains(*obj));

  // Heap is ready, force |ec_page| to become an evacuation candidate and
  // simulate incremental marking.
  FLAG_stress_compaction = true;
  FLAG_manual_evacuation_candidates_selection = true;
  heap::ForceEvacuationCandidate(ec_page);
  heap::SimulateIncrementalMarking(heap);
  // Disable stress compaction mode in order to let GC do scavenge.
  FLAG_stress_compaction = false;

  // Check that everything is ready for triggering incremental write barrier
  // during scavenge (i.e. that |obj| is black and incremental marking is
  // in compacting mode and |obj_value|'s page is an evacuation candidate).
  IncrementalMarking* marking = heap->incremental_marking();
  CHECK(marking->IsCompacting());
  IncrementalMarking::MarkingState* marking_state =
      heap->incremental_marking()->marking_state();
  CHECK(marking_state->IsBlack(*obj));
  CHECK(MarkCompactCollector::IsOnEvacuationCandidate(*obj_value));

  // Trigger GCs so that |obj| moves to old gen.
  CcTest::CollectGarbage(i::NEW_SPACE);  // in survivor space now
  CcTest::CollectGarbage(i::NEW_SPACE);  // in old gen now

  CHECK(isolate->heap()->old_space()->Contains(*obj));
  CHECK(isolate->heap()->old_space()->Contains(*obj_value));
  CHECK(MarkCompactCollector::IsOnEvacuationCandidate(*obj_value));

  CcTest::CollectGarbage(i::OLD_SPACE);

  // |obj_value| must be evacuated.
  CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(*obj_value));

  FieldIndex field_index = FieldIndex::ForDescriptor(*map, 1);
  CHECK_EQ(*obj_value, obj->RawFastPropertyAt(field_index));
}


static void TestLayoutDescriptorHelper(Isolate* isolate,
                                       int inobject_properties,
                                       Handle<DescriptorArray> descriptors,
                                       int number_of_descriptors) {
  Handle<Map> map = Map::Create(isolate, inobject_properties);

  Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
      map, descriptors, descriptors->number_of_descriptors());
  InitializeVerifiedMapDescriptors(*map, *descriptors, *layout_descriptor);

  LayoutDescriptorHelper helper(*map);
  bool all_fields_tagged = true;

  int instance_size = map->instance_size();

  int end_offset = instance_size * 2;
  int first_non_tagged_field_offset = end_offset;
  for (int i = 0; i < number_of_descriptors; i++) {
    PropertyDetails details = descriptors->GetDetails(i);
    if (details.location() != kField) continue;
    FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    if (!index.is_inobject()) continue;
    all_fields_tagged &= !details.representation().IsDouble();
    bool expected_tagged = !index.is_double();
    if (!expected_tagged) {
      first_non_tagged_field_offset =
          Min(first_non_tagged_field_offset, index.offset());
    }

    int end_of_region_offset;
    CHECK_EQ(expected_tagged, helper.IsTagged(index.offset()));
    CHECK_EQ(expected_tagged, helper.IsTagged(index.offset(), instance_size,
                                              &end_of_region_offset));
    CHECK_GT(end_of_region_offset, 0);
    CHECK_EQ(end_of_region_offset % kPointerSize, 0);
    CHECK(end_of_region_offset <= instance_size);

    for (int offset = index.offset(); offset < end_of_region_offset;
         offset += kPointerSize) {
      CHECK_EQ(expected_tagged, helper.IsTagged(index.offset()));
    }
    if (end_of_region_offset < instance_size) {
      CHECK_EQ(!expected_tagged, helper.IsTagged(end_of_region_offset));
    } else {
      CHECK(helper.IsTagged(end_of_region_offset));
    }
  }

  for (int offset = 0; offset < JSObject::kHeaderSize; offset += kPointerSize) {
    // Header queries
    CHECK(helper.IsTagged(offset));
    int end_of_region_offset;
    CHECK(helper.IsTagged(offset, end_offset, &end_of_region_offset));
    CHECK_EQ(first_non_tagged_field_offset, end_of_region_offset);

    // Out of bounds queries
    CHECK(helper.IsTagged(offset + instance_size));
  }

  CHECK_EQ(all_fields_tagged, helper.all_fields_tagged());
}


TEST(LayoutDescriptorHelperMixed) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    props[i] = static_cast<TestPropertyKind>(i % PROP_KIND_NUMBER);
  }
  Handle<DescriptorArray> descriptors =
      CreateDescriptorArray(isolate, props, kPropsCount);

  TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);

  TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);

  TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);

  TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
                             kPropsCount);

  TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
}


TEST(LayoutDescriptorHelperAllTagged) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    props[i] = PROP_TAGGED;
  }
  Handle<DescriptorArray> descriptors =
      CreateDescriptorArray(isolate, props, kPropsCount);

  TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);

  TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);

  TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);

  TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
                             kPropsCount);

  TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
}


TEST(LayoutDescriptorHelperAllDoubles) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<LayoutDescriptor> layout_descriptor;
  const int kPropsCount = kSmiValueSize * 3;
  TestPropertyKind props[kPropsCount];
  for (int i = 0; i < kPropsCount; i++) {
    props[i] = PROP_DOUBLE;
  }
  Handle<DescriptorArray> descriptors =
      CreateDescriptorArray(isolate, props, kPropsCount);

  TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);

  TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);

  TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);

  TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
                             kPropsCount);

  TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
}


TEST(LayoutDescriptorSharing) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();
  Handle<FieldType> any_type = FieldType::Any(isolate);

  Handle<Map> split_map;
  {
    Handle<Map> map = Map::Create(isolate, 64);
    for (int i = 0; i < 32; i++) {
      Handle<String> name = MakeName("prop", i);
      map = Map::CopyWithField(map, name, any_type, NONE, kMutable,
                               Representation::Smi(), INSERT_TRANSITION)
                .ToHandleChecked();
    }
    split_map =
        Map::CopyWithField(map, MakeString("dbl"), any_type, NONE, kMutable,
                           Representation::Double(), INSERT_TRANSITION)
            .ToHandleChecked();
  }
  Handle<LayoutDescriptor> split_layout_descriptor(
      split_map->layout_descriptor(), isolate);
  CHECK(split_layout_descriptor->IsConsistentWithMap(*split_map, true));
  CHECK(split_layout_descriptor->IsSlowLayout());
  CHECK(split_map->owns_descriptors());

  Handle<Map> map1 =
      Map::CopyWithField(split_map, MakeString("foo"), any_type, NONE, kMutable,
                         Representation::Double(), INSERT_TRANSITION)
          .ToHandleChecked();
  CHECK(!split_map->owns_descriptors());
  CHECK_EQ(*split_layout_descriptor, split_map->layout_descriptor());

  // Layout descriptors should be shared with |split_map|.
  CHECK(map1->owns_descriptors());
  CHECK_EQ(*split_layout_descriptor, map1->layout_descriptor());
  CHECK(map1->layout_descriptor()->IsConsistentWithMap(*map1, true));

  Handle<Map> map2 =
      Map::CopyWithField(split_map, MakeString("bar"), any_type, NONE, kMutable,
                         Representation::Tagged(), INSERT_TRANSITION)
          .ToHandleChecked();

  // Layout descriptors should not be shared with |split_map|.
  CHECK(map2->owns_descriptors());
  CHECK_NE(*split_layout_descriptor, map2->layout_descriptor());
  CHECK(map2->layout_descriptor()->IsConsistentWithMap(*map2, true));
}


static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map,
                             int tagged_descriptor, int double_descriptor,
                             bool check_tagged_value = true) {
  FLAG_stress_compaction = true;
  FLAG_manual_evacuation_candidates_selection = true;
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();
  Heap* heap = CcTest::heap();
  PagedSpace* old_space = heap->old_space();

  // The plan: create |obj| by |map| in old space, create |obj_value| in
  // new space and ensure that write barrier is triggered when |obj_value| is
  // written to property |tagged_descriptor| of |obj|.
  // Then migrate object to |new_map| and set proper value for property
  // |double_descriptor|. Call GC and ensure that it did not crash during
  // store buffer entries updating.

  Handle<JSObject> obj;
  Handle<HeapObject> obj_value;
  {
    AlwaysAllocateScope always_allocate(isolate);
    obj = factory->NewJSObjectFromMap(map, TENURED);
    CHECK(old_space->Contains(*obj));

    obj_value = factory->NewHeapNumber(0.);
  }

  CHECK(heap->InNewSpace(*obj_value));

  {
    FieldIndex index = FieldIndex::ForDescriptor(*map, tagged_descriptor);
    const int n = 153;
    for (int i = 0; i < n; i++) {
      obj->FastPropertyAtPut(index, *obj_value);
    }
  }

  // Migrate |obj| to |new_map| which should shift fields and put the
  // |boom_value| to the slot that was earlier recorded by write barrier.
  JSObject::MigrateToMap(obj, new_map);

  Address fake_object = reinterpret_cast<Address>(*obj_value) + kPointerSize;
  uint64_t boom_value = bit_cast<uint64_t>(fake_object);

  FieldIndex double_field_index =
      FieldIndex::ForDescriptor(*new_map, double_descriptor);
  CHECK(obj->IsUnboxedDoubleField(double_field_index));
  obj->RawFastDoublePropertyAsBitsAtPut(double_field_index, boom_value);

  // Trigger GC to evacuate all candidates.
  CcTest::CollectGarbage(NEW_SPACE);

  if (check_tagged_value) {
    FieldIndex tagged_field_index =
        FieldIndex::ForDescriptor(*new_map, tagged_descriptor);
    CHECK_EQ(*obj_value, obj->RawFastPropertyAt(tagged_field_index));
  }
  CHECK_EQ(boom_value, obj->RawFastDoublePropertyAsBitsAt(double_field_index));
}


static void TestIncrementalWriteBarrier(Handle<Map> map, Handle<Map> new_map,
                                        int tagged_descriptor,
                                        int double_descriptor,
                                        bool check_tagged_value = true) {
  if (FLAG_never_compact || !FLAG_incremental_marking) return;
  ManualGCScope manual_gc_scope;
  FLAG_manual_evacuation_candidates_selection = true;
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();
  Heap* heap = CcTest::heap();
  PagedSpace* old_space = heap->old_space();

  // The plan: create |obj| by |map| in old space, create |obj_value| in
  // old space and ensure it end up in evacuation candidate page. Start
  // incremental marking and ensure that incremental write barrier is triggered
  // when |obj_value| is written to property |tagged_descriptor| of |obj|.
  // Then migrate object to |new_map| and set proper value for property
  // |double_descriptor|. Call GC and ensure that it did not crash during
  // slots buffer entries updating.

  Handle<JSObject> obj;
  Handle<HeapObject> obj_value;
  Page* ec_page;
  {
    AlwaysAllocateScope always_allocate(isolate);
    obj = factory->NewJSObjectFromMap(map, TENURED);
    CHECK(old_space->Contains(*obj));

    // Make sure |obj_value| is placed on an old-space evacuation candidate.
    heap::SimulateFullSpace(old_space);
    obj_value = factory->NewJSArray(32 * KB, HOLEY_ELEMENTS, TENURED);
    ec_page = Page::FromAddress(obj_value->address());
    CHECK_NE(ec_page, Page::FromAddress(obj->address()));
  }

  // Heap is ready, force |ec_page| to become an evacuation candidate and
  // simulate incremental marking.
  heap::ForceEvacuationCandidate(ec_page);
  heap::SimulateIncrementalMarking(heap);

  // Check that everything is ready for triggering incremental write barrier
  // (i.e. that both |obj| and |obj_value| are black and the marking phase is
  // still active and |obj_value|'s page is indeed an evacuation candidate).
  IncrementalMarking* marking = heap->incremental_marking();
  CHECK(marking->IsMarking());
  IncrementalMarking::MarkingState* marking_state = marking->marking_state();
  CHECK(marking_state->IsBlack(*obj));
  CHECK(marking_state->IsBlack(*obj_value));
  CHECK(MarkCompactCollector::IsOnEvacuationCandidate(*obj_value));

  // Trigger incremental write barrier, which should add a slot to remembered
  // set.
  {
    FieldIndex index = FieldIndex::ForDescriptor(*map, tagged_descriptor);
    obj->FastPropertyAtPut(index, *obj_value);
  }

  // Migrate |obj| to |new_map| which should shift fields and put the
  // |boom_value| to the slot that was earlier recorded by incremental write
  // barrier.
  JSObject::MigrateToMap(obj, new_map);

  uint64_t boom_value = UINT64_C(0xBAAD0176A37C28E1);

  FieldIndex double_field_index =
      FieldIndex::ForDescriptor(*new_map, double_descriptor);
  CHECK(obj->IsUnboxedDoubleField(double_field_index));
  obj->RawFastDoublePropertyAsBitsAtPut(double_field_index, boom_value);

  // Trigger GC to evacuate all candidates.
  CcTest::CollectGarbage(OLD_SPACE);

  // Ensure that the values are still there and correct.
  CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(*obj_value));

  if (check_tagged_value) {
    FieldIndex tagged_field_index =
        FieldIndex::ForDescriptor(*new_map, tagged_descriptor);
    CHECK_EQ(*obj_value, obj->RawFastPropertyAt(tagged_field_index));
  }
  CHECK_EQ(boom_value, obj->RawFastDoublePropertyAsBitsAt(double_field_index));
}

enum OldToWriteBarrierKind {
  OLD_TO_OLD_WRITE_BARRIER,
  OLD_TO_NEW_WRITE_BARRIER
};
static void TestWriteBarrierObjectShiftFieldsRight(
    OldToWriteBarrierKind write_barrier_kind) {
  ManualGCScope manual_gc_scope;
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(CcTest::isolate());

  Handle<FieldType> any_type = FieldType::Any(isolate);

  CompileRun("function func() { return 1; }");

  Handle<JSObject> func = GetObject("func");

  Handle<Map> map = Map::Create(isolate, 10);
  map = Map::CopyWithConstant(map, MakeName("prop", 0), func, NONE,
                              INSERT_TRANSITION).ToHandleChecked();
  map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, kMutable,
                           Representation::Double(), INSERT_TRANSITION)
            .ToHandleChecked();
  map = Map::CopyWithField(map, MakeName("prop", 2), any_type, NONE, kMutable,
                           Representation::Tagged(), INSERT_TRANSITION)
            .ToHandleChecked();

  // Shift fields right by turning constant property to a field.
  Handle<Map> new_map = Map::ReconfigureProperty(
      map, 0, kData, NONE, Representation::Tagged(), any_type);

  if (write_barrier_kind == OLD_TO_NEW_WRITE_BARRIER) {
    TestWriteBarrier(map, new_map, 2, 1);
  } else {
    CHECK_EQ(OLD_TO_OLD_WRITE_BARRIER, write_barrier_kind);
    TestIncrementalWriteBarrier(map, new_map, 2, 1);
  }
}

TEST(WriteBarrierObjectShiftFieldsRight) {
  TestWriteBarrierObjectShiftFieldsRight(OLD_TO_NEW_WRITE_BARRIER);
}


TEST(IncrementalWriteBarrierObjectShiftFieldsRight) {
  TestWriteBarrierObjectShiftFieldsRight(OLD_TO_OLD_WRITE_BARRIER);
}


// TODO(ishell): add respective tests for property kind reconfiguring from
// accessor field to double, once accessor fields are supported by
// Map::ReconfigureProperty().


// TODO(ishell): add respective tests for fast property removal case once
// Map::ReconfigureProperty() supports that.

#endif

}  // namespace test_unboxed_doubles
}  // namespace internal
}  // namespace v8
