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

#include "src/init/v8.h"
#include "test/cctest/cctest.h"

#include "src/builtins/builtins-constructor.h"
#include "src/debug/debug.h"
#include "src/execution/execution.h"
#include "src/handles/global-handles.h"
#include "src/heap/factory.h"
#include "src/heap/spaces.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/objects-inl.h"
#include "src/roots/roots.h"
#include "test/cctest/heap/heap-utils.h"

namespace v8 {
namespace internal {

namespace {


template<typename HashMap>
static void TestHashMap(Handle<HashMap> table) {
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();

  Handle<JSObject> a = factory->NewJSArray(7);
  Handle<JSObject> b = factory->NewJSArray(11);
  table = HashMap::Put(table, a, b);
  CHECK_EQ(1, table->NumberOfElements());
  CHECK_EQ(table->Lookup(a), *b);
  // When the key does not exist in the map, Lookup returns the hole.
  ReadOnlyRoots roots(CcTest::heap());
  CHECK_EQ(table->Lookup(b), roots.the_hole_value());

  // Keys still have to be valid after objects were moved.
  CcTest::CollectGarbage(NEW_SPACE);
  CHECK_EQ(1, table->NumberOfElements());
  CHECK_EQ(table->Lookup(a), *b);
  CHECK_EQ(table->Lookup(b), roots.the_hole_value());

  // Keys that are overwritten should not change number of elements.
  table = HashMap::Put(table, a, factory->NewJSArray(13));
  CHECK_EQ(1, table->NumberOfElements());
  CHECK_NE(table->Lookup(a), *b);

  // Keys that have been removed are mapped to the hole.
  bool was_present = false;
  table = HashMap::Remove(isolate, table, a, &was_present);
  CHECK(was_present);
  CHECK_EQ(0, table->NumberOfElements());
  CHECK_EQ(table->Lookup(a), roots.the_hole_value());

  // Keys should map back to their respective values and also should get
  // an identity hash code generated.
  for (int i = 0; i < 100; i++) {
    Handle<JSReceiver> key = factory->NewJSArray(7);
    Handle<JSObject> value = factory->NewJSArray(11);
    table = HashMap::Put(table, key, value);
    CHECK_EQ(table->NumberOfElements(), i + 1);
    CHECK(table->FindEntry(isolate, key).is_found());
    CHECK_EQ(table->Lookup(key), *value);
    CHECK(key->GetIdentityHash().IsSmi());
  }

  // Keys never added to the map which already have an identity hash
  // code should not be found.
  for (int i = 0; i < 100; i++) {
    Handle<JSReceiver> key = factory->NewJSArray(7);
    CHECK(key->GetOrCreateIdentityHash(isolate).IsSmi());
    CHECK(table->FindEntry(isolate, key).is_not_found());
    CHECK_EQ(table->Lookup(key), roots.the_hole_value());
    CHECK(key->GetIdentityHash().IsSmi());
  }

  // Keys that don't have an identity hash should not be found and also
  // should not get an identity hash code generated.
  for (int i = 0; i < 100; i++) {
    Handle<JSReceiver> key = factory->NewJSArray(7);
    CHECK_EQ(table->Lookup(key), roots.the_hole_value());
    Object identity_hash = key->GetIdentityHash();
    CHECK_EQ(roots.undefined_value(), identity_hash);
  }
}


TEST(HashMap) {
  LocalContext context;
  v8::HandleScope scope(context->GetIsolate());
  Isolate* isolate = CcTest::i_isolate();
  TestHashMap(ObjectHashTable::New(isolate, 23));
}

template <typename HashSet>
static void TestHashSet(Handle<HashSet> table) {
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();

  Handle<JSObject> a = factory->NewJSArray(7);
  Handle<JSObject> b = factory->NewJSArray(11);
  table = HashSet::Add(isolate, table, a);
  CHECK_EQ(1, table->NumberOfElements());
  CHECK(table->Has(isolate, a));
  CHECK(!table->Has(isolate, b));

  // Keys still have to be valid after objects were moved.
  CcTest::CollectGarbage(NEW_SPACE);
  CHECK_EQ(1, table->NumberOfElements());
  CHECK(table->Has(isolate, a));
  CHECK(!table->Has(isolate, b));

  // Keys that are overwritten should not change number of elements.
  table = HashSet::Add(isolate, table, a);
  CHECK_EQ(1, table->NumberOfElements());
  CHECK(table->Has(isolate, a));
  CHECK(!table->Has(isolate, b));

  // Keys that have been removed are mapped to the hole.
  // TODO(cbruni): not implemented yet.
  // bool was_present = false;
  // table = HashSet::Remove(table, a, &was_present);
  // CHECK(was_present);
  // CHECK_EQ(0, table->NumberOfElements());
  // CHECK(!table->Has(a));
  // CHECK(!table->Has(b));

  // Keys should map back to their respective values and also should get
  // an identity hash code generated.
  for (int i = 0; i < 100; i++) {
    Handle<JSReceiver> key = factory->NewJSArray(7);
    table = HashSet::Add(isolate, table, key);
    CHECK_EQ(table->NumberOfElements(), i + 2);
    CHECK(table->Has(isolate, key));
    CHECK(key->GetIdentityHash().IsSmi());
  }

  // Keys never added to the map which already have an identity hash
  // code should not be found.
  for (int i = 0; i < 100; i++) {
    Handle<JSReceiver> key = factory->NewJSArray(7);
    CHECK(key->GetOrCreateIdentityHash(isolate).IsSmi());
    CHECK(!table->Has(isolate, key));
    CHECK(key->GetIdentityHash().IsSmi());
  }

  // Keys that don't have an identity hash should not be found and also
  // should not get an identity hash code generated.
  for (int i = 0; i < 100; i++) {
    Handle<JSReceiver> key = factory->NewJSArray(7);
    CHECK(!table->Has(isolate, key));
    Object identity_hash = key->GetIdentityHash();
    CHECK_EQ(ReadOnlyRoots(CcTest::heap()).undefined_value(), identity_hash);
  }
}

TEST(HashSet) {
  LocalContext context;
  v8::HandleScope scope(context->GetIsolate());
  Isolate* isolate = CcTest::i_isolate();
  TestHashSet(ObjectHashSet::New(isolate, 23));
}

class ObjectHashTableTest: public ObjectHashTable {
 public:
  explicit ObjectHashTableTest(ObjectHashTable o) : ObjectHashTable(o) {}

  void insert(InternalIndex entry, int key, int value) {
    set(EntryToIndex(entry), Smi::FromInt(key));
    set(EntryToIndex(entry) + 1, Smi::FromInt(value));
  }

  int lookup(int key) {
    Handle<Object> key_obj(Smi::FromInt(key), CcTest::i_isolate());
    return Smi::ToInt(Lookup(key_obj));
  }

  int capacity() {
    return Capacity();
  }
};


TEST(HashTableRehash) {
  LocalContext context;
  Isolate* isolate = CcTest::i_isolate();
  v8::HandleScope scope(context->GetIsolate());
  // Test almost filled table.
  {
    Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 100);
    ObjectHashTableTest t(*table);
    int capacity = t.capacity();
    for (int i = 0; i < capacity - 1; i++) {
      t.insert(InternalIndex(i), i * i, i);
    }
    t.Rehash(isolate);
    for (int i = 0; i < capacity - 1; i++) {
      CHECK_EQ(i, t.lookup(i * i));
    }
  }
  // Test half-filled table.
  {
    Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 100);
    ObjectHashTableTest t(*table);
    int capacity = t.capacity();
    for (int i = 0; i < capacity / 2; i++) {
      t.insert(InternalIndex(i), i * i, i);
    }
    t.Rehash(isolate);
    for (int i = 0; i < capacity / 2; i++) {
      CHECK_EQ(i, t.lookup(i * i));
    }
  }
}


#ifdef DEBUG
template<class HashSet>
static void TestHashSetCausesGC(Handle<HashSet> table) {
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();

  Handle<JSObject> key = factory->NewJSArray(0);

  // Simulate a full heap so that generating an identity hash code
  // in subsequent calls will request GC.
  heap::SimulateFullSpace(CcTest::heap()->new_space());
  heap::SimulateFullSpace(CcTest::heap()->old_space());

  // Calling Contains() should not cause GC ever.
  int gc_count = isolate->heap()->gc_count();
  CHECK(!table->Contains(key));
  CHECK(gc_count == isolate->heap()->gc_count());

  // Calling Remove() will not cause GC in this case.
  bool was_present = false;
  table = HashSet::Remove(table, key, &was_present);
  CHECK(!was_present);
  CHECK(gc_count == isolate->heap()->gc_count());

  // Calling Add() should cause GC.
  table = HashSet::Add(table, key);
  CHECK(gc_count < isolate->heap()->gc_count());
}
#endif


#ifdef DEBUG
template <class HashMap>
static void TestHashMapDoesNotCauseGC(Handle<HashMap> table) {
  Isolate* isolate = CcTest::i_isolate();
  Factory* factory = isolate->factory();

  Handle<JSObject> key = factory->NewJSArray(0);

  // Even though we simulate a full heap, generating an identity hash
  // code in subsequent calls will not request GC.
  if (!FLAG_single_generation) {
    heap::SimulateFullSpace(CcTest::heap()->new_space());
  }
  heap::SimulateFullSpace(CcTest::heap()->old_space());

  // Calling Lookup() should not cause GC ever.
  CHECK(table->Lookup(key).IsTheHole(isolate));

  // Calling Put() should request GC by returning a failure.
  int gc_count = isolate->heap()->gc_count();
  HashMap::Put(table, key, key);
  CHECK(gc_count == isolate->heap()->gc_count());
}


TEST(ObjectHashTableCausesGC) {
  i::FLAG_stress_compaction = false;
  // For SimulateFullSpace in TestHashMapDoesNotCauseGC.
  i::FLAG_stress_concurrent_allocation = false;
  LocalContext context;
  v8::HandleScope scope(context->GetIsolate());
  Isolate* isolate = CcTest::i_isolate();
  TestHashMapDoesNotCauseGC(ObjectHashTable::New(isolate, 1));
}
#endif

TEST(MaximumClonedShallowObjectProperties) {
  // Assert that a NameDictionary with kMaximumClonedShallowObjectProperties is
  // not in large-object space.
  const int max_capacity = NameDictionary::ComputeCapacity(
      ConstructorBuiltins::kMaximumClonedShallowObjectProperties);
  const InternalIndex max_literal_entry(max_capacity /
                                        NameDictionary::kEntrySize);
  const int max_literal_index = NameDictionary::EntryToIndex(max_literal_entry);
  CHECK_LE(NameDictionary::OffsetOfElementAt(max_literal_index),
           kMaxRegularHeapObjectSize);
}

}  // namespace

}  // namespace internal
}  // namespace v8
