// Copyright 2017 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/init/v8.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"
#include "src/objects/ordered-hash-table.h"
#include "src/third_party/siphash/halfsiphash.h"
#include "src/utils/utils.h"

#include "test/cctest/cctest.h"

namespace v8 {
namespace internal {

int AddToSetAndGetHash(Isolate* isolate, Handle<JSObject> obj,
                       bool has_fast_properties) {
  CHECK_EQ(has_fast_properties, obj->HasFastProperties());
  CHECK_EQ(ReadOnlyRoots(isolate).undefined_value(), obj->GetHash());
  Handle<OrderedHashSet> set = isolate->factory()->NewOrderedHashSet();
  OrderedHashSet::Add(isolate, set, obj);
  CHECK_EQ(has_fast_properties, obj->HasFastProperties());
  return Smi::ToInt(obj->GetHash());
}

void CheckFastObject(Handle<JSObject> obj, int hash) {
  CHECK(obj->HasFastProperties());
  CHECK(obj->raw_properties_or_hash().IsPropertyArray());
  CHECK_EQ(Smi::FromInt(hash), obj->GetHash());
  CHECK_EQ(hash, obj->property_array().Hash());
}

void CheckDictionaryObject(Handle<JSObject> obj, int hash) {
  CHECK(!obj->HasFastProperties());
  CHECK(obj->raw_properties_or_hash().IsNameDictionary());
  CHECK_EQ(Smi::FromInt(hash), obj->GetHash());
  CHECK_EQ(hash, obj->property_dictionary().Hash());
}

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

  Handle<JSObject> obj =
      isolate->factory()->NewJSObject(isolate->object_function());
  CHECK(obj->HasFastProperties());

  int hash = AddToSetAndGetHash(isolate, obj, true);
  CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash());
}

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

  const char* source = " var x = { a: 1};";
  CompileRun(source);

  Handle<JSObject> obj = GetGlobal<JSObject>("x");
  CHECK_EQ(ReadOnlyRoots(isolate).empty_fixed_array(),
           obj->raw_properties_or_hash());

  int hash = AddToSetAndGetHash(isolate, obj, true);
  CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash());
}

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

  const char* source =
      " var x = {}; "
      " x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; ";
  CompileRun(source);

  Handle<JSObject> obj = GetGlobal<JSObject>("x");
  CHECK(obj->HasFastProperties());

  int hash = AddToSetAndGetHash(isolate, obj, true);
  CheckFastObject(obj, hash);
}

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

  Handle<JSObject> obj =
      isolate->factory()->NewJSObject(isolate->object_function());
  CHECK(obj->HasFastProperties());
  JSObject::NormalizeProperties(isolate, obj, CLEAR_INOBJECT_PROPERTIES, 0,
                                "cctest/test-hashcode");
  CHECK(obj->raw_properties_or_hash().IsNameDictionary());

  int hash = AddToSetAndGetHash(isolate, obj, false);
  CheckDictionaryObject(obj, hash);
}

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

  const char* source =
      " var x = { };"
      " x.a = 1; x.b = 2; x.c = 3; x.d = 4;";
  CompileRun(source);

  Handle<JSObject> obj = GetGlobal<JSObject>("x");
  CHECK(obj->HasFastProperties());

  int hash = AddToSetAndGetHash(isolate, obj, true);
  CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash());

  int length = obj->property_array().length();
  CompileRun("x.e = 5;");
  CHECK(obj->property_array().length() > length);
  CheckFastObject(obj, hash);
}

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

  const char* source =
      " var x = { };"
      " x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; ";
  CompileRun(source);

  Handle<JSObject> obj = GetGlobal<JSObject>("x");
  CHECK(obj->raw_properties_or_hash().IsPropertyArray());

  int hash = AddToSetAndGetHash(isolate, obj, true);
  CHECK_EQ(hash, obj->property_array().Hash());

  int length = obj->property_array().length();
  CompileRun("x.f = 2; x.g = 5; x.h = 2");
  CHECK(obj->property_array().length() > length);
  CheckFastObject(obj, hash);
}

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

  const char* source =
      " var x = { };"
      " x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; ";
  CompileRun(source);

  Handle<JSObject> obj = GetGlobal<JSObject>("x");
  CHECK(obj->raw_properties_or_hash().IsPropertyArray());

  int hash = AddToSetAndGetHash(isolate, obj, true);
  CHECK(obj->raw_properties_or_hash().IsPropertyArray());
  CHECK_EQ(hash, obj->property_array().Hash());

  JSObject::NormalizeProperties(isolate, obj, KEEP_INOBJECT_PROPERTIES, 0,
                                "cctest/test-hashcode");
  CheckDictionaryObject(obj, hash);
}

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

  const char* source = " var x = {}; ";
  CompileRun(source);

  Handle<JSObject> obj = GetGlobal<JSObject>("x");
  JSObject::NormalizeProperties(isolate, obj, CLEAR_INOBJECT_PROPERTIES, 0,
                                "cctest/test-hashcode");
  CHECK(obj->raw_properties_or_hash().IsNameDictionary());

  int hash = AddToSetAndGetHash(isolate, obj, false);
  CHECK_EQ(hash, obj->property_dictionary().Hash());

  int length = obj->property_dictionary().length();
  CompileRun("for(var i = 0; i < 10; i++) { x['f'+i] = i };");
  CHECK(obj->property_dictionary().length() > length);
  CheckDictionaryObject(obj, hash);
}

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

  Handle<JSObject> obj =
      isolate->factory()->NewJSObject(isolate->object_function());
  JSObject::NormalizeProperties(isolate, obj, CLEAR_INOBJECT_PROPERTIES, 0,
                                "cctest/test-hashcode");
  CHECK(obj->raw_properties_or_hash().IsNameDictionary());

  int hash = AddToSetAndGetHash(isolate, obj, false);
  CHECK_EQ(hash, obj->property_dictionary().Hash());

  JSObject::MigrateSlowToFast(obj, 0, "cctest/test-hashcode");
  CHECK_EQ(Smi::FromInt(hash), obj->GetHash());
}

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

  const char* source =
      " var x = Object.create(null); "
      " for(var i = 0; i < 10; i++) { x['f'+i] = i }; ";
  CompileRun(source);

  Handle<JSObject> obj = GetGlobal<JSObject>("x");
  CHECK(obj->raw_properties_or_hash().IsNameDictionary());

  int hash = AddToSetAndGetHash(isolate, obj, false);
  CHECK_EQ(hash, obj->property_dictionary().Hash());

  JSObject::MigrateSlowToFast(obj, 0, "cctest/test-hashcode");
  CheckFastObject(obj, hash);
}

namespace {

using HashFunction = uint32_t (*)(uint32_t key, uint64_t seed);

void TestIntegerHashQuality(const int samples_log2, int num_buckets_log2,
                            uint64_t seed, double max_var,
                            HashFunction hash_function) {
  int samples = 1 << samples_log2;
  int num_buckets = 1 << num_buckets_log2;
  int mean = samples / num_buckets;
  int* buckets = new int[num_buckets];

  for (int i = 0; i < num_buckets; i++) buckets[i] = 0;

  for (int i = 0; i < samples; i++) {
    uint32_t hash = hash_function(i, seed);
    buckets[hash % num_buckets]++;
  }

  int sum_deviation = 0;
  for (int i = 0; i < num_buckets; i++) {
    int deviation = abs(buckets[i] - mean);
    sum_deviation += deviation * deviation;
  }
  delete[] buckets;

  double variation_coefficient = sqrt(sum_deviation * 1.0 / num_buckets) / mean;

  printf("samples: 1 << %2d, buckets: 1 << %2d, var_coeff: %0.3f\n",
         samples_log2, num_buckets_log2, variation_coefficient);
  CHECK_LT(variation_coefficient, max_var);
}
uint32_t HalfSipHash(uint32_t key, uint64_t seed) {
  return halfsiphash(key, seed);
}

uint32_t JenkinsHash(uint32_t key, uint64_t seed) {
  return ComputeLongHash(static_cast<uint64_t>(key) ^ seed);
}

uint32_t DefaultHash(uint32_t key, uint64_t seed) {
  return ComputeSeededHash(key, seed);
}
}  // anonymous namespace

void TestIntegerHashQuality(HashFunction hash_function) {
  TestIntegerHashQuality(17, 13, 0x123456789ABCDEFU, 0.4, hash_function);
  TestIntegerHashQuality(16, 12, 0x123456789ABCDEFU, 0.4, hash_function);
  TestIntegerHashQuality(15, 11, 0xFEDCBA987654321U, 0.4, hash_function);
  TestIntegerHashQuality(14, 10, 0xFEDCBA987654321U, 0.4, hash_function);
  TestIntegerHashQuality(13, 9, 1, 0.4, hash_function);
  TestIntegerHashQuality(12, 8, 1, 0.4, hash_function);

  TestIntegerHashQuality(17, 10, 0x123456789ABCDEFU, 0.2, hash_function);
  TestIntegerHashQuality(16, 9, 0x123456789ABCDEFU, 0.2, hash_function);
  TestIntegerHashQuality(15, 8, 0xFEDCBA987654321U, 0.2, hash_function);
  TestIntegerHashQuality(14, 7, 0xFEDCBA987654321U, 0.2, hash_function);
  TestIntegerHashQuality(13, 6, 1, 0.2, hash_function);
  TestIntegerHashQuality(12, 5, 1, 0.2, hash_function);
}

TEST(HalfSipHashQuality) { TestIntegerHashQuality(HalfSipHash); }

TEST(JenkinsHashQuality) { TestIntegerHashQuality(JenkinsHash); }

TEST(DefaultHashQuality) { TestIntegerHashQuality(DefaultHash); }

}  // namespace internal
}  // namespace v8
