// Copyright 2015 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 <sstream>
#include <utility>

#include "src/api.h"
#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/v8.h"

#include "test/cctest/cctest.h"

namespace v8 {
namespace internal {
namespace test_inobject_slack_tracking {

static const int kMaxInobjectProperties = JSObject::kMaxInObjectProperties;

template <typename T>
static Handle<T> OpenHandle(v8::Local<v8::Value> value) {
  Handle<Object> obj = v8::Utils::OpenHandle(*value);
  return Handle<T>::cast(obj);
}


static inline v8::Local<v8::Value> Run(v8::Local<v8::Script> script) {
  v8::Local<v8::Value> result;
  if (script->Run(v8::Isolate::GetCurrent()->GetCurrentContext())
          .ToLocal(&result)) {
    return result;
  }
  return v8::Local<v8::Value>();
}



template <typename T = Object>
Handle<T> GetLexical(const char* name) {
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();

  Handle<String> str_name = factory->InternalizeUtf8String(name);
  Handle<ScriptContextTable> script_contexts(
      isolate->native_context()->script_context_table());

  ScriptContextTable::LookupResult lookup_result;
  if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) {
    Handle<Object> result =
        FixedArray::get(*ScriptContextTable::GetContext(
                            script_contexts, lookup_result.context_index),
                        lookup_result.slot_index, isolate);
    return Handle<T>::cast(result);
  }
  return Handle<T>();
}


template <typename T = Object>
Handle<T> GetLexical(const std::string& name) {
  return GetLexical<T>(name.c_str());
}

template <typename T>
static inline Handle<T> RunI(v8::Local<v8::Script> script) {
  return OpenHandle<T>(Run(script));
}

template <typename T>
static inline Handle<T> CompileRunI(const char* script) {
  return OpenHandle<T>(CompileRun(script));
}


static Object* GetFieldValue(JSObject* obj, int property_index) {
  FieldIndex index = FieldIndex::ForPropertyIndex(obj->map(), property_index);
  return obj->RawFastPropertyAt(index);
}


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();
  }
}


static double GetDoubleFieldValue(JSObject* obj, int property_index) {
  FieldIndex index = FieldIndex::ForPropertyIndex(obj->map(), property_index);
  return GetDoubleFieldValue(obj, index);
}


bool IsObjectShrinkable(JSObject* obj) {
  Handle<Map> filler_map =
      CcTest::i_isolate()->factory()->one_pointer_filler_map();

  int inobject_properties = obj->map()->GetInObjectProperties();
  int unused = obj->map()->UnusedPropertyFields();
  if (unused == 0) return false;

  for (int i = inobject_properties - unused; i < inobject_properties; i++) {
    if (*filler_map != GetFieldValue(obj, i)) {
      return false;
    }
  }
  return true;
}


TEST(JSObjectBasic) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  const char* source =
      "function A() {"
      "  this.a = 42;"
      "  this.d = 4.2;"
      "  this.o = this;"
      "}";
  CompileRun(source);

  Handle<JSFunction> func = GetGlobal<JSFunction>("A");

  // Zero instances were created so far.
  CHECK(!func->has_initial_map());

  v8::Local<v8::Script> new_A_script = v8_compile("new A();");

  Handle<JSObject> obj = RunI<JSObject>(new_A_script);

  CHECK(func->has_initial_map());
  Handle<Map> initial_map(func->initial_map());

  // One instance created.
  CHECK_EQ(Map::kSlackTrackingCounterStart - 1,
           initial_map->construction_counter());
  CHECK(initial_map->IsInobjectSlackTrackingInProgress());

  // There must be at least some slack.
  CHECK_LT(5, obj->map()->GetInObjectProperties());
  CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj, 0));
  CHECK_EQ(4.2, GetDoubleFieldValue(*obj, 1));
  CHECK_EQ(*obj, GetFieldValue(*obj, 2));
  CHECK(IsObjectShrinkable(*obj));

  // Create several objects to complete the tracking.
  for (int i = 1; i < Map::kGenerousAllocationCount; i++) {
    CHECK(initial_map->IsInobjectSlackTrackingInProgress());
    Handle<JSObject> tmp = RunI<JSObject>(new_A_script);
    CHECK_EQ(initial_map->IsInobjectSlackTrackingInProgress(),
             IsObjectShrinkable(*tmp));
  }
  CHECK(!initial_map->IsInobjectSlackTrackingInProgress());
  CHECK(!IsObjectShrinkable(*obj));

  // No slack left.
  CHECK_EQ(3, obj->map()->GetInObjectProperties());
}


TEST(JSObjectBasicNoInlineNew) {
  FLAG_inline_new = false;
  TestJSObjectBasic();
}


TEST(JSObjectComplex) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  const char* source =
      "function A(n) {"
      "  if (n > 0) this.a = 42;"
      "  if (n > 1) this.d = 4.2;"
      "  if (n > 2) this.o1 = this;"
      "  if (n > 3) this.o2 = this;"
      "  if (n > 4) this.o3 = this;"
      "  if (n > 5) this.o4 = this;"
      "}";
  CompileRun(source);

  Handle<JSFunction> func = GetGlobal<JSFunction>("A");

  // Zero instances were created so far.
  CHECK(!func->has_initial_map());

  Handle<JSObject> obj1 = CompileRunI<JSObject>("new A(1);");
  Handle<JSObject> obj3 = CompileRunI<JSObject>("new A(3);");
  Handle<JSObject> obj5 = CompileRunI<JSObject>("new A(5);");

  CHECK(func->has_initial_map());
  Handle<Map> initial_map(func->initial_map());

  // Three instances created.
  CHECK_EQ(Map::kSlackTrackingCounterStart - 3,
           initial_map->construction_counter());
  CHECK(initial_map->IsInobjectSlackTrackingInProgress());

  // There must be at least some slack.
  CHECK_LT(5, obj3->map()->GetInObjectProperties());
  CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj3, 0));
  CHECK_EQ(4.2, GetDoubleFieldValue(*obj3, 1));
  CHECK_EQ(*obj3, GetFieldValue(*obj3, 2));
  CHECK(IsObjectShrinkable(*obj1));
  CHECK(IsObjectShrinkable(*obj3));
  CHECK(IsObjectShrinkable(*obj5));

  // Create several objects to complete the tracking.
  for (int i = 3; i < Map::kGenerousAllocationCount; i++) {
    CHECK(initial_map->IsInobjectSlackTrackingInProgress());
    CompileRun("new A(3);");
  }
  CHECK(!initial_map->IsInobjectSlackTrackingInProgress());

  // obj1 and obj2 stays shrinkable because we don't clear unused fields.
  CHECK(IsObjectShrinkable(*obj1));
  CHECK(IsObjectShrinkable(*obj3));
  CHECK(!IsObjectShrinkable(*obj5));

  CHECK_EQ(5, obj1->map()->GetInObjectProperties());
  CHECK_EQ(4, obj1->map()->UnusedPropertyFields());

  CHECK_EQ(5, obj3->map()->GetInObjectProperties());
  CHECK_EQ(2, obj3->map()->UnusedPropertyFields());

  CHECK_EQ(5, obj5->map()->GetInObjectProperties());
  CHECK_EQ(0, obj5->map()->UnusedPropertyFields());

  // Since slack tracking is complete, the new objects should not be shrinkable.
  obj1 = CompileRunI<JSObject>("new A(1);");
  obj3 = CompileRunI<JSObject>("new A(3);");
  obj5 = CompileRunI<JSObject>("new A(5);");

  CHECK(!IsObjectShrinkable(*obj1));
  CHECK(!IsObjectShrinkable(*obj3));
  CHECK(!IsObjectShrinkable(*obj5));
}


TEST(JSObjectComplexNoInlineNew) {
  FLAG_inline_new = false;
  TestJSObjectComplex();
}


TEST(JSGeneratorObjectBasic) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  const char* source =
      "function* A() {"
      "  var i = 0;"
      "  while(true) {"
      "    yield i++;"
      "  }"
      "};"
      "function CreateGenerator() {"
      "  var o = A();"
      "  o.a = 42;"
      "  o.d = 4.2;"
      "  o.o = o;"
      "  return o;"
      "}";
  CompileRun(source);

  Handle<JSFunction> func = GetGlobal<JSFunction>("A");

  // Zero instances were created so far.
  CHECK(!func->has_initial_map());

  v8::Local<v8::Script> new_A_script = v8_compile("CreateGenerator();");

  Handle<JSObject> obj = RunI<JSObject>(new_A_script);

  CHECK(func->has_initial_map());
  Handle<Map> initial_map(func->initial_map());

  // One instance created.
  CHECK_EQ(Map::kSlackTrackingCounterStart - 1,
           initial_map->construction_counter());
  CHECK(initial_map->IsInobjectSlackTrackingInProgress());

  // There must be at least some slack.
  CHECK_LT(5, obj->map()->GetInObjectProperties());
  CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj, 0));
  CHECK_EQ(4.2, GetDoubleFieldValue(*obj, 1));
  CHECK_EQ(*obj, GetFieldValue(*obj, 2));
  CHECK(IsObjectShrinkable(*obj));

  // Create several objects to complete the tracking.
  for (int i = 1; i < Map::kGenerousAllocationCount; i++) {
    CHECK(initial_map->IsInobjectSlackTrackingInProgress());
    Handle<JSObject> tmp = RunI<JSObject>(new_A_script);
    CHECK_EQ(initial_map->IsInobjectSlackTrackingInProgress(),
             IsObjectShrinkable(*tmp));
  }
  CHECK(!initial_map->IsInobjectSlackTrackingInProgress());
  CHECK(!IsObjectShrinkable(*obj));

  // No slack left.
  CHECK_EQ(3, obj->map()->GetInObjectProperties());
}


TEST(JSGeneratorObjectBasicNoInlineNew) {
  FLAG_inline_new = false;
  TestJSGeneratorObjectBasic();
}


TEST(SubclassBasicNoBaseClassInstances) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  // Check that base class' and subclass' slack tracking do not interfere with
  // each other.
  // In this test we never create base class instances.

  const char* source =
      "'use strict';"
      "class A {"
      "  constructor(...args) {"
      "    this.aa = 42;"
      "    this.ad = 4.2;"
      "    this.ao = this;"
      "  }"
      "};"
      "class B extends A {"
      "  constructor(...args) {"
      "    super(...args);"
      "    this.ba = 142;"
      "    this.bd = 14.2;"
      "    this.bo = this;"
      "  }"
      "};";
  CompileRun(source);

  Handle<JSFunction> a_func = GetLexical<JSFunction>("A");
  Handle<JSFunction> b_func = GetLexical<JSFunction>("B");

  // Zero instances were created so far.
  CHECK(!a_func->has_initial_map());
  CHECK(!b_func->has_initial_map());

  v8::Local<v8::Script> new_B_script = v8_compile("new B();");

  Handle<JSObject> obj = RunI<JSObject>(new_B_script);

  CHECK(a_func->has_initial_map());
  Handle<Map> a_initial_map(a_func->initial_map());

  CHECK(b_func->has_initial_map());
  Handle<Map> b_initial_map(b_func->initial_map());

  // Zero instances of A created.
  CHECK_EQ(Map::kSlackTrackingCounterStart,
           a_initial_map->construction_counter());
  CHECK(a_initial_map->IsInobjectSlackTrackingInProgress());

  // One instance of B created.
  CHECK_EQ(Map::kSlackTrackingCounterStart - 1,
           b_initial_map->construction_counter());
  CHECK(b_initial_map->IsInobjectSlackTrackingInProgress());

  // There must be at least some slack.
  CHECK_LT(10, obj->map()->GetInObjectProperties());
  CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj, 0));
  CHECK_EQ(4.2, GetDoubleFieldValue(*obj, 1));
  CHECK_EQ(*obj, GetFieldValue(*obj, 2));
  CHECK_EQ(Smi::FromInt(142), GetFieldValue(*obj, 3));
  CHECK_EQ(14.2, GetDoubleFieldValue(*obj, 4));
  CHECK_EQ(*obj, GetFieldValue(*obj, 5));
  CHECK(IsObjectShrinkable(*obj));

  // Create several subclass instances to complete the tracking.
  for (int i = 1; i < Map::kGenerousAllocationCount; i++) {
    CHECK(b_initial_map->IsInobjectSlackTrackingInProgress());
    Handle<JSObject> tmp = RunI<JSObject>(new_B_script);
    CHECK_EQ(b_initial_map->IsInobjectSlackTrackingInProgress(),
             IsObjectShrinkable(*tmp));
  }
  CHECK(!b_initial_map->IsInobjectSlackTrackingInProgress());
  CHECK(!IsObjectShrinkable(*obj));

  // Zero instances of A created.
  CHECK_EQ(Map::kSlackTrackingCounterStart,
           a_initial_map->construction_counter());
  CHECK(a_initial_map->IsInobjectSlackTrackingInProgress());

  // No slack left.
  CHECK_EQ(6, obj->map()->GetInObjectProperties());
}


TEST(SubclassBasicNoBaseClassInstancesNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassBasicNoBaseClassInstances();
}


TEST(SubclassBasic) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  // Check that base class' and subclass' slack tracking do not interfere with
  // each other.
  // In this test we first create enough base class instances to complete
  // the slack tracking and then proceed creating subclass instances.

  const char* source =
      "'use strict';"
      "class A {"
      "  constructor(...args) {"
      "    this.aa = 42;"
      "    this.ad = 4.2;"
      "    this.ao = this;"
      "  }"
      "};"
      "class B extends A {"
      "  constructor(...args) {"
      "    super(...args);"
      "    this.ba = 142;"
      "    this.bd = 14.2;"
      "    this.bo = this;"
      "  }"
      "};";
  CompileRun(source);

  Handle<JSFunction> a_func = GetLexical<JSFunction>("A");
  Handle<JSFunction> b_func = GetLexical<JSFunction>("B");

  // Zero instances were created so far.
  CHECK(!a_func->has_initial_map());
  CHECK(!b_func->has_initial_map());

  v8::Local<v8::Script> new_A_script = v8_compile("new A();");
  v8::Local<v8::Script> new_B_script = v8_compile("new B();");

  Handle<JSObject> a_obj = RunI<JSObject>(new_A_script);
  Handle<JSObject> b_obj = RunI<JSObject>(new_B_script);

  CHECK(a_func->has_initial_map());
  Handle<Map> a_initial_map(a_func->initial_map());

  CHECK(b_func->has_initial_map());
  Handle<Map> b_initial_map(b_func->initial_map());

  // One instance of a base class created.
  CHECK_EQ(Map::kSlackTrackingCounterStart - 1,
           a_initial_map->construction_counter());
  CHECK(a_initial_map->IsInobjectSlackTrackingInProgress());

  // One instance of a subclass created.
  CHECK_EQ(Map::kSlackTrackingCounterStart - 1,
           b_initial_map->construction_counter());
  CHECK(b_initial_map->IsInobjectSlackTrackingInProgress());

  // Create several base class instances to complete the tracking.
  for (int i = 1; i < Map::kGenerousAllocationCount; i++) {
    CHECK(a_initial_map->IsInobjectSlackTrackingInProgress());
    Handle<JSObject> tmp = RunI<JSObject>(new_A_script);
    CHECK_EQ(a_initial_map->IsInobjectSlackTrackingInProgress(),
             IsObjectShrinkable(*tmp));
  }
  CHECK(!a_initial_map->IsInobjectSlackTrackingInProgress());
  CHECK(!IsObjectShrinkable(*a_obj));

  // No slack left.
  CHECK_EQ(3, a_obj->map()->GetInObjectProperties());

  // There must be at least some slack.
  CHECK_LT(10, b_obj->map()->GetInObjectProperties());
  CHECK_EQ(Smi::FromInt(42), GetFieldValue(*b_obj, 0));
  CHECK_EQ(4.2, GetDoubleFieldValue(*b_obj, 1));
  CHECK_EQ(*b_obj, GetFieldValue(*b_obj, 2));
  CHECK_EQ(Smi::FromInt(142), GetFieldValue(*b_obj, 3));
  CHECK_EQ(14.2, GetDoubleFieldValue(*b_obj, 4));
  CHECK_EQ(*b_obj, GetFieldValue(*b_obj, 5));
  CHECK(IsObjectShrinkable(*b_obj));

  // Create several subclass instances to complete the tracking.
  for (int i = 1; i < Map::kGenerousAllocationCount; i++) {
    CHECK(b_initial_map->IsInobjectSlackTrackingInProgress());
    Handle<JSObject> tmp = RunI<JSObject>(new_B_script);
    CHECK_EQ(b_initial_map->IsInobjectSlackTrackingInProgress(),
             IsObjectShrinkable(*tmp));
  }
  CHECK(!b_initial_map->IsInobjectSlackTrackingInProgress());
  CHECK(!IsObjectShrinkable(*b_obj));

  // No slack left.
  CHECK_EQ(6, b_obj->map()->GetInObjectProperties());
}


TEST(SubclassBasicNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassBasic();
}


// Creates class hierarchy of length matching the |hierarchy_desc| length and
// with the number of fields at i'th level equal to |hierarchy_desc[i]|.
static void CreateClassHierarchy(const std::vector<int>& hierarchy_desc) {
  std::ostringstream os;
  os << "'use strict';\n\n";

  int n = static_cast<int>(hierarchy_desc.size());
  for (int cur_class = 0; cur_class < n; cur_class++) {
    os << "class A" << cur_class;
    if (cur_class > 0) {
      os << " extends A" << (cur_class - 1);
    }
    os << " {\n"
          "  constructor(...args) {\n";
    if (cur_class > 0) {
      os << "    super(...args);\n";
    }
    int fields_count = hierarchy_desc[cur_class];
    for (int k = 0; k < fields_count; k++) {
      os << "    this.f" << cur_class << "_" << k << " = " << k << ";\n";
    }
    os << "  }\n"
          "};\n\n";
  }
  CompileRun(os.str().c_str());
}


static std::string GetClassName(int class_index) {
  std::ostringstream os;
  os << "A" << class_index;
  return os.str();
}


static v8::Local<v8::Script> GetNewObjectScript(const std::string& class_name) {
  std::ostringstream os;
  os << "new " << class_name << "();";
  return v8_compile(os.str().c_str());
}


// Test that in-object slack tracking works as expected for first |n| classes
// in the hierarchy.
// This test works only for if the total property count is less than maximum
// in-object properties count.
static void TestClassHierarchy(const std::vector<int>& hierarchy_desc, int n) {
  int fields_count = 0;
  for (int cur_class = 0; cur_class < n; cur_class++) {
    std::string class_name = GetClassName(cur_class);
    int fields_count_at_current_level = hierarchy_desc[cur_class];
    fields_count += fields_count_at_current_level;

    // This test is not suitable for in-object properties count overflow case.
    CHECK_LT(fields_count, kMaxInobjectProperties);

    // Create |class_name| objects and check slack tracking.
    v8::Local<v8::Script> new_script = GetNewObjectScript(class_name);

    Handle<JSFunction> func = GetLexical<JSFunction>(class_name);

    Handle<JSObject> obj = RunI<JSObject>(new_script);

    CHECK(func->has_initial_map());
    Handle<Map> initial_map(func->initial_map());

    // If the object is slow-mode already, bail out.
    if (obj->map()->is_dictionary_map()) continue;

    // There must be at least some slack.
    CHECK_LT(fields_count, obj->map()->GetInObjectProperties());

    // One instance was created.
    CHECK_EQ(Map::kSlackTrackingCounterStart - 1,
             initial_map->construction_counter());
    CHECK(initial_map->IsInobjectSlackTrackingInProgress());

    // Create several instances to complete the tracking.
    for (int i = 1; i < Map::kGenerousAllocationCount; i++) {
      CHECK(initial_map->IsInobjectSlackTrackingInProgress());
      Handle<JSObject> tmp = RunI<JSObject>(new_script);
      CHECK_EQ(initial_map->IsInobjectSlackTrackingInProgress(),
               IsObjectShrinkable(*tmp));
      if (!initial_map->IsInobjectSlackTrackingInProgress()) {
        // Turbofan can force completion of in-object slack tracking.
        break;
      }
      CHECK_EQ(Map::kSlackTrackingCounterStart - i - 1,
               initial_map->construction_counter());
    }
    CHECK(!initial_map->IsInobjectSlackTrackingInProgress());
    CHECK(!IsObjectShrinkable(*obj));

    // No slack left.
    CHECK_EQ(fields_count, obj->map()->GetInObjectProperties());
  }
}


static void TestSubclassChain(const std::vector<int>& hierarchy_desc) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  CreateClassHierarchy(hierarchy_desc);
  TestClassHierarchy(hierarchy_desc, static_cast<int>(hierarchy_desc.size()));
}

TEST(Subclasses) {
  std::vector<int> hierarchy_desc;
  hierarchy_desc.push_back(50);
  hierarchy_desc.push_back(128);
  TestSubclassChain(hierarchy_desc);
}

TEST(LongSubclassChain1) {
  std::vector<int> hierarchy_desc;
  for (int i = 0; i < 7; i++) {
    hierarchy_desc.push_back(i * 10);
  }
  TestSubclassChain(hierarchy_desc);
}


TEST(LongSubclassChain2) {
  std::vector<int> hierarchy_desc;
  hierarchy_desc.push_back(10);
  for (int i = 0; i < 42; i++) {
    hierarchy_desc.push_back(0);
  }
  hierarchy_desc.push_back(230);
  TestSubclassChain(hierarchy_desc);
}


TEST(LongSubclassChain3) {
  std::vector<int> hierarchy_desc;
  for (int i = 0; i < 42; i++) {
    hierarchy_desc.push_back(5);
  }
  TestSubclassChain(hierarchy_desc);
}


TEST(InobjectPropetiesCountOverflowInSubclass) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  std::vector<int> hierarchy_desc;
  const int kNoOverflowCount = 5;
  for (int i = 0; i < kNoOverflowCount; i++) {
    hierarchy_desc.push_back(50);
  }
  // In this class we are going to have properties in the backing store.
  hierarchy_desc.push_back(100);

  CreateClassHierarchy(hierarchy_desc);

  // For the last class in the hierarchy we need different checks.
  {
    int cur_class = kNoOverflowCount;
    std::string class_name = GetClassName(cur_class);

    // Create |class_name| objects and check slack tracking.
    v8::Local<v8::Script> new_script = GetNewObjectScript(class_name);

    Handle<JSFunction> func = GetLexical<JSFunction>(class_name);

    Handle<JSObject> obj = RunI<JSObject>(new_script);

    CHECK(func->has_initial_map());
    Handle<Map> initial_map(func->initial_map());

    // There must be no slack left.
    CHECK_EQ(JSObject::kMaxInstanceSize, obj->map()->instance_size());
    CHECK_EQ(kMaxInobjectProperties, obj->map()->GetInObjectProperties());

    // One instance was created.
    CHECK_EQ(Map::kSlackTrackingCounterStart - 1,
             initial_map->construction_counter());
    CHECK(initial_map->IsInobjectSlackTrackingInProgress());

    // Create several instances to complete the tracking.
    for (int i = 1; i < Map::kGenerousAllocationCount; i++) {
      CHECK(initial_map->IsInobjectSlackTrackingInProgress());
      Handle<JSObject> tmp = RunI<JSObject>(new_script);
      CHECK(!IsObjectShrinkable(*tmp));
    }
    CHECK(!initial_map->IsInobjectSlackTrackingInProgress());
    CHECK(!IsObjectShrinkable(*obj));

    // No slack left.
    CHECK_EQ(kMaxInobjectProperties, obj->map()->GetInObjectProperties());
  }

  // The other classes in the hierarchy are not affected.
  TestClassHierarchy(hierarchy_desc, kNoOverflowCount);
}

static void CheckExpectedProperties(int expected, std::ostringstream& os) {
  Handle<HeapObject> obj = Handle<HeapObject>::cast(
      v8::Utils::OpenHandle(*CompileRun(os.str().c_str())));
  CHECK_EQ(expected, obj->map()->GetInObjectProperties());
}

TEST(ObjectLiteralPropertyBackingStoreSize) {
  v8::HandleScope scope(CcTest::isolate());
  LocalContext env;

  std::ostringstream os;

  // An index key does not require space in the property backing store.
  os << "(function() {\n"
        "  function f() {\n"
        "    var o = {\n"
        "      '-1': 42,\n"  // Allocate for non-index key.
        "      1: 42,\n"     // Do not allocate for index key.
        "      '2': 42\n"    // Do not allocate for index key.
        "    };\n"
        "    return o;\n"
        "  }\n"
        "\n"
        "  return f();\n"
        "} )();";
  CheckExpectedProperties(1, os);

  // Avoid over-/under-allocation for computed property names.
  os << "(function() {\n"
        "  'use strict';\n"
        "  function f(x) {\n"
        "    var o = {\n"
        "      1: 42,\n"    // Do not allocate for index key.
        "      '2': 42,\n"  // Do not allocate for index key.
        "      [x]: 42,\n"  // Allocate for property with computed name.
        "      3: 42,\n"    // Do not allocate for index key.
        "      '4': 42\n"   // Do not allocate for index key.
        "    };\n"
        "    return o;\n"
        "  }\n"
        "\n"
        "  var x = 'hello'\n"
        "\n"
        "  return f(x);\n"
        "} )();";
  CheckExpectedProperties(1, os);

  // Conversion to index key.
  os << "(function() {\n"
        "  function f(x) {\n"
        "    var o = {\n"
        "      1: 42,\n"       // Do not allocate for index key.
        "      '2': 42,\n"     // Do not allocate for index key.
        "      [x]: 42,\n"     // Allocate for property with computed name.
        "      3: 42,\n"       // Do not allocate for index key.
        "      get 12() {}\n"  // Do not allocate for index key.
        "    };\n"
        "    return o;\n"
        "  }\n"
        "\n"
        "  var x = 'hello'\n"
        "\n"
        "  return f(x);\n"
        "} )();";
  CheckExpectedProperties(1, os);

  os << "(function() {\n"
        "  function f() {\n"
        "    var o = {};\n"
        "    return o;\n"
        "  }\n"
        "\n"
        "  return f();\n"
        "} )();";
  // Empty objects have slack for 4 properties.
  CheckExpectedProperties(4, os);

  os << "(function() {\n"
        "  function f(x) {\n"
        "    var o = {\n"
        "      a: 42,\n"    // Allocate for constant property.
        "      [x]: 42,\n"  // Allocate for property with computed name.
        "      b: 42\n"     // Allocate for constant property.
        "    };\n"
        "    return o;\n"
        "  }\n"
        "\n"
        "  var x = 'hello'\n"
        "\n"
        "  return f(x);\n"
        "} )();";
  CheckExpectedProperties(3, os);

  os << "(function() {\n"
        "  function f(x) {\n"
        "    var o = {\n"
        "      a: 42,\n"          // Allocate for constant property.
        "      __proto__: 42,\n"  // Do not allocate for __proto__.
        "      [x]: 42\n"         // Allocate for property with computed name.
        "    };\n"
        "    return o;\n"
        "  }\n"
        "\n"
        "  var x = 'hello'\n"
        "\n"
        "  return f(x);\n"
        "} )();";
  // __proto__ is not allocated in the backing store.
  CheckExpectedProperties(2, os);

  os << "(function() {\n"
        "  function f(x) {\n"
        "    var o = {\n"
        "      a: 42,\n"         // Allocate for constant property.
        "      [x]: 42,\n"       // Allocate for property with computed name.
        "      __proto__: 42\n"  // Do not allocate for __proto__.
        "    };\n"
        "    return o;\n"
        "  }\n"
        "\n"
        "  var x = 'hello'\n"
        "\n"
        "  return f(x);\n"
        "} )();";
  CheckExpectedProperties(2, os);
}

TEST(SlowModeSubclass) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  std::vector<int> hierarchy_desc;
  const int kNoOverflowCount = 5;
  for (int i = 0; i < kNoOverflowCount; i++) {
    hierarchy_desc.push_back(50);
  }
  // This class should go dictionary mode.
  hierarchy_desc.push_back(1000);

  CreateClassHierarchy(hierarchy_desc);

  // For the last class in the hierarchy we need different checks.
  {
    int cur_class = kNoOverflowCount;
    std::string class_name = GetClassName(cur_class);

    // Create |class_name| objects and check slack tracking.
    v8::Local<v8::Script> new_script = GetNewObjectScript(class_name);

    Handle<JSFunction> func = GetLexical<JSFunction>(class_name);

    Handle<JSObject> obj = RunI<JSObject>(new_script);

    CHECK(func->has_initial_map());
    Handle<Map> initial_map(func->initial_map());

    // Object should go dictionary mode.
    CHECK_EQ(JSObject::kHeaderSize, obj->map()->instance_size());
    CHECK(obj->map()->is_dictionary_map());

    // One instance was created.
    CHECK_EQ(Map::kSlackTrackingCounterStart - 1,
             initial_map->construction_counter());
    CHECK(initial_map->IsInobjectSlackTrackingInProgress());

    // Create several instances to complete the tracking.
    for (int i = 1; i < Map::kGenerousAllocationCount; i++) {
      CHECK(initial_map->IsInobjectSlackTrackingInProgress());
      Handle<JSObject> tmp = RunI<JSObject>(new_script);
      CHECK(!IsObjectShrinkable(*tmp));
    }
    CHECK(!initial_map->IsInobjectSlackTrackingInProgress());
    CHECK(!IsObjectShrinkable(*obj));

    // Object should stay in dictionary mode.
    CHECK_EQ(JSObject::kHeaderSize, obj->map()->instance_size());
    CHECK(obj->map()->is_dictionary_map());
  }

  // The other classes in the hierarchy are not affected.
  TestClassHierarchy(hierarchy_desc, kNoOverflowCount);
}


static void TestSubclassBuiltin(const char* subclass_name,
                                InstanceType instance_type,
                                const char* builtin_name,
                                const char* ctor_arguments = "",
                                int builtin_properties_count = 0) {
  {
    std::ostringstream os;
    os << "'use strict';\n"
          "class "
       << subclass_name << " extends " << builtin_name
       << " {\n"
          "  constructor(...args) {\n"
          "    super(...args);\n"
          "    this.a = 42;\n"
          "    this.d = 4.2;\n"
          "    this.o = this;\n"
          "  }\n"
          "};\n";
    CompileRun(os.str().c_str());
  }

  Handle<JSFunction> func = GetLexical<JSFunction>(subclass_name);

  // Zero instances were created so far.
  CHECK(!func->has_initial_map());

  v8::Local<v8::Script> new_script;
  {
    std::ostringstream os;
    os << "new " << subclass_name << "(" << ctor_arguments << ");";
    new_script = v8_compile(os.str().c_str());
  }

  RunI<JSObject>(new_script);

  CHECK(func->has_initial_map());
  Handle<Map> initial_map(func->initial_map());

  CHECK_EQ(instance_type, initial_map->instance_type());

  // One instance of a subclass created.
  CHECK_EQ(Map::kSlackTrackingCounterStart - 1,
           initial_map->construction_counter());
  CHECK(initial_map->IsInobjectSlackTrackingInProgress());

  // Create two instances in order to ensure that |obj|.o is a data field
  // in case of Function subclassing.
  Handle<JSObject> obj = RunI<JSObject>(new_script);

  // Two instances of a subclass created.
  CHECK_EQ(Map::kSlackTrackingCounterStart - 2,
           initial_map->construction_counter());
  CHECK(initial_map->IsInobjectSlackTrackingInProgress());

  // There must be at least some slack.
  CHECK_LT(builtin_properties_count + 5, obj->map()->GetInObjectProperties());
  CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj, builtin_properties_count + 0));
  CHECK_EQ(4.2, GetDoubleFieldValue(*obj, builtin_properties_count + 1));
  CHECK_EQ(*obj, GetFieldValue(*obj, builtin_properties_count + 2));
  CHECK(IsObjectShrinkable(*obj));

  // Create several subclass instances to complete the tracking.
  for (int i = 2; i < Map::kGenerousAllocationCount; i++) {
    CHECK(initial_map->IsInobjectSlackTrackingInProgress());
    Handle<JSObject> tmp = RunI<JSObject>(new_script);
    CHECK_EQ(initial_map->IsInobjectSlackTrackingInProgress(),
             IsObjectShrinkable(*tmp));
  }
  CHECK(!initial_map->IsInobjectSlackTrackingInProgress());
  CHECK(!IsObjectShrinkable(*obj));

  // No slack left.
  CHECK_EQ(builtin_properties_count + 3, obj->map()->GetInObjectProperties());

  CHECK_EQ(instance_type, obj->map()->instance_type());
}


TEST(SubclassObjectBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_OBJECT_TYPE, "Object", "true");
  TestSubclassBuiltin("A2", JS_OBJECT_TYPE, "Object", "42");
  TestSubclassBuiltin("A3", JS_OBJECT_TYPE, "Object", "'some string'");
}


TEST(SubclassObjectBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassObjectBuiltin();
}


TEST(SubclassFunctionBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_FUNCTION_TYPE, "Function", "'return 153;'");
  TestSubclassBuiltin("A2", JS_FUNCTION_TYPE, "Function", "'this.a = 44;'");
}


TEST(SubclassFunctionBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassFunctionBuiltin();
}


TEST(SubclassBooleanBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_VALUE_TYPE, "Boolean", "true");
  TestSubclassBuiltin("A2", JS_VALUE_TYPE, "Boolean", "false");
}


TEST(SubclassBooleanBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassBooleanBuiltin();
}


TEST(SubclassErrorBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  const int first_field = 2;
  TestSubclassBuiltin("A1", JS_ERROR_TYPE, "Error", "'err'", first_field);
  TestSubclassBuiltin("A2", JS_ERROR_TYPE, "EvalError", "'err'", first_field);
  TestSubclassBuiltin("A3", JS_ERROR_TYPE, "RangeError", "'err'", first_field);
  TestSubclassBuiltin("A4", JS_ERROR_TYPE, "ReferenceError", "'err'",
                      first_field);
  TestSubclassBuiltin("A5", JS_ERROR_TYPE, "SyntaxError", "'err'", first_field);
  TestSubclassBuiltin("A6", JS_ERROR_TYPE, "TypeError", "'err'", first_field);
  TestSubclassBuiltin("A7", JS_ERROR_TYPE, "URIError", "'err'", first_field);
}


TEST(SubclassErrorBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassErrorBuiltin();
}


TEST(SubclassNumberBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_VALUE_TYPE, "Number", "42");
  TestSubclassBuiltin("A2", JS_VALUE_TYPE, "Number", "4.2");
}


TEST(SubclassNumberBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassNumberBuiltin();
}


TEST(SubclassDateBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_DATE_TYPE, "Date", "123456789");
}


TEST(SubclassDateBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassDateBuiltin();
}


TEST(SubclassStringBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_VALUE_TYPE, "String", "'some string'");
  TestSubclassBuiltin("A2", JS_VALUE_TYPE, "String", "");
}


TEST(SubclassStringBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassStringBuiltin();
}


TEST(SubclassRegExpBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  const int first_field = 1;
  TestSubclassBuiltin("A1", JS_REGEXP_TYPE, "RegExp", "'o(..)h', 'g'",
                      first_field);
}


TEST(SubclassRegExpBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassRegExpBuiltin();
}


TEST(SubclassArrayBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_ARRAY_TYPE, "Array", "42");
}


TEST(SubclassArrayBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassArrayBuiltin();
}


TEST(SubclassTypedArrayBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

#define TYPED_ARRAY_TEST(Type, type, TYPE, elementType, size) \
  TestSubclassBuiltin("A" #Type, JS_TYPED_ARRAY_TYPE, #Type "Array", "42");

  TYPED_ARRAYS(TYPED_ARRAY_TEST)

#undef TYPED_ARRAY_TEST
}


TEST(SubclassTypedArrayBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassTypedArrayBuiltin();
}


TEST(SubclassCollectionBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_SET_TYPE, "Set", "");
  TestSubclassBuiltin("A2", JS_MAP_TYPE, "Map", "");
  TestSubclassBuiltin("A3", JS_WEAK_SET_TYPE, "WeakSet", "");
  TestSubclassBuiltin("A4", JS_WEAK_MAP_TYPE, "WeakMap", "");
}


TEST(SubclassCollectionBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassCollectionBuiltin();
}


TEST(SubclassArrayBufferBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_ARRAY_BUFFER_TYPE, "ArrayBuffer", "42");
  TestSubclassBuiltin("A2", JS_DATA_VIEW_TYPE, "DataView",
                      "new ArrayBuffer(42)");
}


TEST(SubclassArrayBufferBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassArrayBufferBuiltin();
}


TEST(SubclassPromiseBuiltin) {
  // Avoid eventual completion of in-object slack tracking.
  FLAG_always_opt = false;
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());

  TestSubclassBuiltin("A1", JS_PROMISE_TYPE, "Promise",
                      "function(resolve, reject) { resolve('ok'); }");
}


TEST(SubclassPromiseBuiltinNoInlineNew) {
  FLAG_inline_new = false;
  TestSubclassPromiseBuiltin();
}

}  // namespace test_inobject_slack_tracking
}  // namespace internal
}  // namespace v8
