Index: test/cctest/test-closemap.cc |
diff --git a/test/cctest/test-dictionary.cc b/test/cctest/test-closemap.cc |
similarity index 50% |
copy from test/cctest/test-dictionary.cc |
copy to test/cctest/test-closemap.cc |
index 6e62a2243c26eed0e00222abc2e44930be05a145..e93acfb9de43ae7aca58362e182ddeb771c8cd69 100644 |
--- a/test/cctest/test-dictionary.cc |
+++ b/test/cctest/test-closemap.cc |
@@ -1,4 +1,4 @@ |
-// Copyright 2011 the V8 project authors. All rights reserved. |
+// Copyright 2014 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: |
@@ -25,29 +25,144 @@ |
// (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 <stdlib.h> |
+ |
#include "v8.h" |
-#include "api.h" |
-#include "debug.h" |
-#include "execution.h" |
-#include "factory.h" |
-#include "macro-assembler.h" |
-#include "objects.h" |
-#include "global-handles.h" |
#include "cctest.h" |
+#include "factory.h" |
+ |
+#include "close-table.h" |
+ |
+namespace { |
using namespace v8::internal; |
+TEST(Set) { |
+ LocalContext context; |
+ Isolate* isolate = CcTest::i_isolate(); |
+ Factory* factory = isolate->factory(); |
+ HandleScope scope(isolate); |
+ Handle<CloseTableSet> close_set = factory->NewCloseTableSet(); |
+ CHECK_EQ(2, close_set->NumberOfBuckets()); |
+ CHECK_EQ(0, close_set->NumberOfElements()); |
+ CHECK_EQ(0, close_set->NumberOfDeletedElements()); |
+ |
+ Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
+ Handle<JSObject> obj = factory->NewJSObjectFromMap(map); |
+ CHECK(!close_set->Contains(*obj)); |
+ close_set = CloseTableSet::Add(close_set, obj); |
+ CHECK_EQ(1, close_set->NumberOfElements()); |
+ CHECK(close_set->Contains(*obj)); |
+ close_set = CloseTableSet::Remove(close_set, obj); |
+ CHECK_EQ(0, close_set->NumberOfElements()); |
+ CHECK(!close_set->Contains(*obj)); |
+ |
+ // Test for collisions/chaining |
+ Handle<JSObject> obj1 = factory->NewJSObjectFromMap(map); |
+ close_set = CloseTableSet::Add(close_set, obj1); |
+ Handle<JSObject> obj2 = factory->NewJSObjectFromMap(map); |
+ close_set = CloseTableSet::Add(close_set, obj2); |
+ Handle<JSObject> obj3 = factory->NewJSObjectFromMap(map); |
+ close_set = CloseTableSet::Add(close_set, obj3); |
+ CHECK_EQ(3, close_set->NumberOfElements()); |
+ CHECK(close_set->Contains(*obj1)); |
+ CHECK(close_set->Contains(*obj2)); |
+ CHECK(close_set->Contains(*obj3)); |
+ |
+ // Test growth |
+ close_set = CloseTableSet::Add(close_set, obj); |
+ Handle<JSObject> obj4 = factory->NewJSObjectFromMap(map); |
+ close_set = CloseTableSet::Add(close_set, obj4); |
+ CHECK(close_set->Contains(*obj)); |
+ CHECK(close_set->Contains(*obj1)); |
+ CHECK(close_set->Contains(*obj2)); |
+ CHECK(close_set->Contains(*obj3)); |
+ CHECK(close_set->Contains(*obj4)); |
+ CHECK_EQ(5, close_set->NumberOfElements()); |
+ CHECK_EQ(0, close_set->NumberOfDeletedElements()); |
+ CHECK_EQ(4, close_set->NumberOfBuckets()); |
+ |
+ // Test shrinking |
+ close_set = CloseTableSet::Remove(close_set, obj); |
+ close_set = CloseTableSet::Remove(close_set, obj1); |
+ close_set = CloseTableSet::Remove(close_set, obj2); |
+ close_set = CloseTableSet::Remove(close_set, obj3); |
+ CHECK_EQ(1, close_set->NumberOfElements()); |
+ CHECK_EQ(2, close_set->NumberOfBuckets()); |
+} |
+ |
+TEST(Map) { |
+ LocalContext context; |
+ Isolate* isolate = CcTest::i_isolate(); |
+ Factory* factory = isolate->factory(); |
+ HandleScope scope(isolate); |
+ Handle<CloseTableMap> close_map = factory->NewCloseTableMap(); |
+ CHECK_EQ(2, close_map->NumberOfBuckets()); |
+ CHECK_EQ(0, close_map->NumberOfElements()); |
+ CHECK_EQ(0, close_map->NumberOfDeletedElements()); |
+ |
+ Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
+ Handle<JSObject> obj = factory->NewJSObjectFromMap(map); |
+ Handle<JSObject> val = factory->NewJSObjectFromMap(map); |
+ CHECK(close_map->Lookup(*obj)->IsTheHole()); |
+ close_map = CloseTableMap::Put(close_map, obj, val); |
+ CHECK_EQ(1, close_map->NumberOfElements()); |
+ CHECK(close_map->Lookup(*obj)->SameValue(*val)); |
+ close_map = CloseTableMap::Put(close_map, obj, factory->the_hole_value()); |
+ CHECK_EQ(0, close_map->NumberOfElements()); |
+ CHECK(close_map->Lookup(*obj)->IsTheHole()); |
+ |
+ // Test for collisions/chaining |
+ Handle<JSObject> obj1 = factory->NewJSObjectFromMap(map); |
+ Handle<JSObject> obj2 = factory->NewJSObjectFromMap(map); |
+ Handle<JSObject> obj3 = factory->NewJSObjectFromMap(map); |
+ Handle<JSObject> val1 = factory->NewJSObjectFromMap(map); |
+ Handle<JSObject> val2 = factory->NewJSObjectFromMap(map); |
+ Handle<JSObject> val3 = factory->NewJSObjectFromMap(map); |
+ close_map = CloseTableMap::Put(close_map, obj1, val1); |
+ close_map = CloseTableMap::Put(close_map, obj2, val2); |
+ close_map = CloseTableMap::Put(close_map, obj3, val3); |
+ CHECK_EQ(3, close_map->NumberOfElements()); |
+ CHECK(close_map->Lookup(*obj1)->SameValue(*val1)); |
+ CHECK(close_map->Lookup(*obj2)->SameValue(*val2)); |
+ CHECK(close_map->Lookup(*obj3)->SameValue(*val3)); |
+ |
+ // Test growth |
+ close_map = CloseTableMap::Put(close_map, obj, val); |
+ Handle<JSObject> obj4 = factory->NewJSObjectFromMap(map); |
+ Handle<JSObject> val4 = factory->NewJSObjectFromMap(map); |
+ close_map = CloseTableMap::Put(close_map, obj4, val4); |
+ CHECK(close_map->Lookup(*obj)->SameValue(*val)); |
+ CHECK(close_map->Lookup(*obj1)->SameValue(*val1)); |
+ CHECK(close_map->Lookup(*obj2)->SameValue(*val2)); |
+ CHECK(close_map->Lookup(*obj3)->SameValue(*val3)); |
+ CHECK(close_map->Lookup(*obj4)->SameValue(*val4)); |
+ CHECK_EQ(5, close_map->NumberOfElements()); |
+ CHECK_EQ(4, close_map->NumberOfBuckets()); |
+ |
+ // Test shrinking |
+ close_map = CloseTableMap::Put(close_map, obj, factory->the_hole_value()); |
+ close_map = CloseTableMap::Put(close_map, obj1, factory->the_hole_value()); |
+ close_map = CloseTableMap::Put(close_map, obj2, factory->the_hole_value()); |
+ close_map = CloseTableMap::Put(close_map, obj3, factory->the_hole_value()); |
+ CHECK_EQ(1, close_map->NumberOfElements()); |
+ CHECK_EQ(2, close_map->NumberOfBuckets()); |
+} |
+ |
+// --------------------------------------------------------- |
+// BELOW THIS LINE TESTS WERE CONVERTED FROM test-dictionary |
+// --------------------------------------------------------- |
TEST(ObjectHashTable) { |
LocalContext context; |
Isolate* isolate = CcTest::i_isolate(); |
Factory* factory = isolate->factory(); |
v8::HandleScope scope(context->GetIsolate()); |
- Handle<ObjectHashTable> table = factory->NewObjectHashTable(23); |
+ Handle<CloseTableMap> table = factory->NewCloseTableMap(); |
Handle<JSObject> a = factory->NewJSArray(7); |
Handle<JSObject> b = factory->NewJSArray(11); |
- table = ObjectHashTable::Put(table, a, b); |
+ table = CloseTableMap::Put(table, a, b); |
CHECK_EQ(table->NumberOfElements(), 1); |
CHECK_EQ(table->Lookup(*a), *b); |
CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value()); |
@@ -59,14 +174,14 @@ TEST(ObjectHashTable) { |
CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value()); |
// Keys that are overwritten should not change number of elements. |
- table = ObjectHashTable::Put(table, a, factory->NewJSArray(13)); |
+ table = CloseTableMap::Put(table, a, factory->NewJSArray(13)); |
CHECK_EQ(table->NumberOfElements(), 1); |
CHECK_NE(table->Lookup(*a), *b); |
// Keys mapped to the hole should be removed permanently. |
- table = ObjectHashTable::Put(table, a, factory->the_hole_value()); |
+ table = CloseTableMap::Put(table, a, factory->the_hole_value()); |
CHECK_EQ(table->NumberOfElements(), 0); |
- CHECK_EQ(table->NumberOfDeletedElements(), 1); |
+ //CHECK_EQ(table->NumberOfDeletedElements(), 1); |
CHECK_EQ(table->Lookup(*a), CcTest::heap()->the_hole_value()); |
// Keys should map back to their respective values and also should get |
@@ -74,9 +189,9 @@ TEST(ObjectHashTable) { |
for (int i = 0; i < 100; i++) { |
Handle<JSReceiver> key = factory->NewJSArray(7); |
Handle<JSObject> value = factory->NewJSArray(11); |
- table = ObjectHashTable::Put(table, key, value); |
+ table = CloseTableMap::Put(table, key, value); |
CHECK_EQ(table->NumberOfElements(), i + 1); |
- CHECK_NE(table->FindEntry(*key), ObjectHashTable::kNotFound); |
+ CHECK_NE(table->FindEntry(*key), CloseTableMap::kNotFound); |
CHECK_EQ(table->Lookup(*key), *value); |
CHECK(key->GetIdentityHash()->IsSmi()); |
} |
@@ -86,7 +201,7 @@ TEST(ObjectHashTable) { |
for (int i = 0; i < 100; i++) { |
Handle<JSReceiver> key = factory->NewJSArray(7); |
CHECK(JSReceiver::GetOrCreateIdentityHash(key)->IsSmi()); |
- CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound); |
+ CHECK_EQ(table->FindEntry(*key), CloseTableMap::kNotFound); |
CHECK_EQ(table->Lookup(*key), CcTest::heap()->the_hole_value()); |
CHECK(key->GetIdentityHash()->IsSmi()); |
} |
@@ -102,65 +217,14 @@ TEST(ObjectHashTable) { |
} |
-class ObjectHashTableTest: public ObjectHashTable { |
- public: |
- void insert(int entry, int key, int value) { |
- set(EntryToIndex(entry), Smi::FromInt(key)); |
- set(EntryToIndex(entry) + 1, Smi::FromInt(value)); |
- } |
- |
- int lookup(int key) { |
- return Smi::cast(Lookup(Smi::FromInt(key)))->value(); |
- } |
- |
- int capacity() { |
- return Capacity(); |
- } |
-}; |
- |
- |
-TEST(HashTableRehash) { |
- LocalContext context; |
- Isolate* isolate = CcTest::i_isolate(); |
- Factory* factory = isolate->factory(); |
- v8::HandleScope scope(context->GetIsolate()); |
- // Test almost filled table. |
- { |
- Handle<ObjectHashTable> table = factory->NewObjectHashTable(100); |
- ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table); |
- int capacity = t->capacity(); |
- for (int i = 0; i < capacity - 1; i++) { |
- t->insert(i, i * i, i); |
- } |
- t->Rehash(Smi::FromInt(0)); |
- for (int i = 0; i < capacity - 1; i++) { |
- CHECK_EQ(i, t->lookup(i * i)); |
- } |
- } |
- // Test half-filled table. |
- { |
- Handle<ObjectHashTable> table = factory->NewObjectHashTable(100); |
- ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table); |
- int capacity = t->capacity(); |
- for (int i = 0; i < capacity / 2; i++) { |
- t->insert(i, i * i, i); |
- } |
- t->Rehash(Smi::FromInt(0)); |
- for (int i = 0; i < capacity / 2; i++) { |
- CHECK_EQ(i, t->lookup(i * i)); |
- } |
- } |
-} |
- |
- |
#ifdef DEBUG |
-TEST(ObjectHashSetCausesGC) { |
+TEST(CloseTableSetCausesGC) { |
i::FLAG_stress_compaction = false; |
LocalContext context; |
Isolate* isolate = CcTest::i_isolate(); |
Factory* factory = isolate->factory(); |
v8::HandleScope scope(context->GetIsolate()); |
- Handle<ObjectHashSet> table = factory->NewObjectHashSet(1); |
+ Handle<CloseTableSet> table = factory->NewCloseTableSet(); |
Handle<JSObject> key = factory->NewJSArray(0); |
v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key); |
@@ -180,24 +244,24 @@ TEST(ObjectHashSetCausesGC) { |
CHECK(gc_count == isolate->heap()->gc_count()); |
// Calling Remove() will not cause GC in this case. |
- table = ObjectHashSet::Remove(table, key); |
+ table = CloseTableSet::Remove(table, key); |
CHECK(gc_count == isolate->heap()->gc_count()); |
// Calling Add() should cause GC. |
- table = ObjectHashSet::Add(table, key); |
+ table = CloseTableSet::Add(table, key); |
CHECK(gc_count < isolate->heap()->gc_count()); |
} |
#endif |
#ifdef DEBUG |
-TEST(ObjectHashTableCausesGC) { |
+TEST(CloseTableMapCausesGC) { |
i::FLAG_stress_compaction = false; |
LocalContext context; |
Isolate* isolate = CcTest::i_isolate(); |
Factory* factory = isolate->factory(); |
v8::HandleScope scope(context->GetIsolate()); |
- Handle<ObjectHashTable> table = factory->NewObjectHashTable(1); |
+ Handle<CloseTableMap> table = factory->NewCloseTableMap(); |
Handle<JSObject> key = factory->NewJSArray(0); |
v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key); |
@@ -216,7 +280,9 @@ TEST(ObjectHashTableCausesGC) { |
// Calling Put() should request GC by returning a failure. |
int gc_count = isolate->heap()->gc_count(); |
- ObjectHashTable::Put(table, key, key); |
+ CloseTableMap::Put(table, key, key); |
CHECK(gc_count < isolate->heap()->gc_count()); |
} |
#endif |
+ |
+} |