// 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(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(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(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(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 {

typedef uint32_t (*HashFunction)(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
