| Index: test/cctest/test-hunique.cc
|
| diff --git a/test/cctest/test-hunique.cc b/test/cctest/test-hunique.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7effb89116727a805a2c4dbb19e3281bcff23896
|
| --- /dev/null
|
| +++ b/test/cctest/test-hunique.cc
|
| @@ -0,0 +1,473 @@
|
| +// Copyright 2013 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 <stdlib.h>
|
| +
|
| +#include "v8.h"
|
| +
|
| +#include "factory.h"
|
| +#include "global-handles.h"
|
| +#include "hydrogen.h"
|
| +#include "cctest.h"
|
| +
|
| +using namespace v8::internal;
|
| +
|
| +TEST(HUniqueCreate) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + Handle<String> A = factory->InternalizeUtf8String("A");
|
| + HUnique<String> HA(A);
|
| +
|
| + CHECK_NE(0, HA.Hashcode());
|
| + CHECK(*HA.handle() == *A);
|
| + CHECK_EQ(*A, *HA.handle());
|
| +
|
| + HUnique<String> HA2(A);
|
| +
|
| + CHECK_EQ(HA.Hashcode(), HA2.Hashcode());
|
| + CHECK(HA == HA2);
|
| + CHECK_EQ(*HA.handle(), *HA2.handle());
|
| +
|
| + CHECK_EQ(HA2.Hashcode(), HA.Hashcode());
|
| + CHECK(HA2 == HA);
|
| + CHECK_EQ(*HA2.handle(), *HA.handle());
|
| +
|
| + Handle<String> B = factory->InternalizeUtf8String("B");
|
| + HUnique<String> HB(B);
|
| +
|
| + CHECK_NE(HA.Hashcode(), HB.Hashcode());
|
| + CHECK(HA != HB);
|
| + CHECK_NE(*HA.handle(), *HB.handle());
|
| +
|
| + CHECK_NE(HB.Hashcode(), HA.Hashcode());
|
| + CHECK(HB != HA);
|
| + CHECK_NE(*HB.handle(), *HA.handle());
|
| +
|
| + // TODO(titzer): check that HUnique properly survives a GC.
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSubsume) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + Handle<String> A = factory->InternalizeUtf8String("A");
|
| + HUnique<String> HA(A);
|
| +
|
| + CHECK_NE(0, HA.Hashcode());
|
| + CHECK(*HA.handle() == *A);
|
| + CHECK_EQ(*A, *HA.handle());
|
| +
|
| + HUnique<Object> HO = HA; // Here comes the subsumption, boys.
|
| +
|
| + CHECK_EQ(HA.Hashcode(), HO.Hashcode());
|
| + CHECK(HA == HO);
|
| + CHECK_EQ(*HA.handle(), *HO.handle());
|
| +
|
| + CHECK_EQ(HO.Hashcode(), HA.Hashcode());
|
| + CHECK(HO == HA);
|
| + CHECK_EQ(*HO.handle(), *HA.handle());
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSet_Add) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + HUnique<String> A(factory->InternalizeUtf8String("A"));
|
| + HUnique<String> B(factory->InternalizeUtf8String("B"));
|
| + HUnique<String> C(factory->InternalizeUtf8String("C"));
|
| +
|
| + Zone zone(isolate);
|
| +
|
| + HUniqueSet<String>* set = new(&zone) HUniqueSet<String>();
|
| +
|
| + CHECK_EQ(0, set->size());
|
| + set->Add(A, &zone);
|
| + CHECK_EQ(1, set->size());
|
| + set->Add(A, &zone);
|
| + CHECK_EQ(1, set->size());
|
| + set->Add(B, &zone);
|
| + CHECK_EQ(2, set->size());
|
| + set->Add(C, &zone);
|
| + CHECK_EQ(3, set->size());
|
| + set->Add(C, &zone);
|
| + CHECK_EQ(3, set->size());
|
| + set->Add(B, &zone);
|
| + CHECK_EQ(3, set->size());
|
| + set->Add(A, &zone);
|
| + CHECK_EQ(3, set->size());
|
| +}
|
| +
|
| +
|
| +template <class T>
|
| +static void CHECK_SETS(
|
| + HUniqueSet<T>* set1, HUniqueSet<T>* set2, bool expected) {
|
| + CHECK(set1->Equals(set1));
|
| + CHECK(set2->Equals(set2));
|
| + CHECK(expected == set1->Equals(set2));
|
| + CHECK(expected == set2->Equals(set1));
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSet_Equals) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + HUnique<String> A(factory->InternalizeUtf8String("A"));
|
| + HUnique<String> B(factory->InternalizeUtf8String("B"));
|
| + HUnique<String> C(factory->InternalizeUtf8String("C"));
|
| +
|
| + Zone zone(isolate);
|
| +
|
| + HUniqueSet<String>* set1 = new(&zone) HUniqueSet<String>();
|
| + HUniqueSet<String>* set2 = new(&zone) HUniqueSet<String>();
|
| +
|
| + CHECK_SETS(set1, set2, true);
|
| +
|
| + set1->Add(A, &zone);
|
| +
|
| + CHECK_SETS(set1, set2, false);
|
| +
|
| + set2->Add(A, &zone);
|
| +
|
| + CHECK_SETS(set1, set2, true);
|
| +
|
| + set1->Add(B, &zone);
|
| +
|
| + CHECK_SETS(set1, set2, false);
|
| +
|
| + set2->Add(C, &zone);
|
| +
|
| + CHECK_SETS(set1, set2, false);
|
| +
|
| + set1->Add(C, &zone);
|
| +
|
| + CHECK_SETS(set1, set2, false);
|
| +
|
| + set2->Add(B, &zone);
|
| +
|
| + CHECK_SETS(set1, set2, true);
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSet_IsSubset1) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + HUnique<String> A(factory->InternalizeUtf8String("A"));
|
| + HUnique<String> B(factory->InternalizeUtf8String("B"));
|
| + HUnique<String> C(factory->InternalizeUtf8String("C"));
|
| +
|
| + Zone zone(isolate);
|
| +
|
| + HUniqueSet<String>* set1 = new(&zone) HUniqueSet<String>();
|
| + HUniqueSet<String>* set2 = new(&zone) HUniqueSet<String>();
|
| +
|
| + CHECK(set1->IsSubset(set2));
|
| + CHECK(set2->IsSubset(set1));
|
| +
|
| + set1->Add(A, &zone);
|
| +
|
| + CHECK(!set1->IsSubset(set2));
|
| + CHECK(set2->IsSubset(set1));
|
| +
|
| + set2->Add(B, &zone);
|
| +
|
| + CHECK(!set1->IsSubset(set2));
|
| + CHECK(!set2->IsSubset(set1));
|
| +
|
| + set2->Add(A, &zone);
|
| +
|
| + CHECK(set1->IsSubset(set2));
|
| + CHECK(!set2->IsSubset(set1));
|
| +
|
| + set1->Add(B, &zone);
|
| +
|
| + CHECK(set1->IsSubset(set2));
|
| + CHECK(set2->IsSubset(set1));
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSet_IsSubset2) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + HUnique<String> A(factory->InternalizeUtf8String("A"));
|
| + HUnique<String> B(factory->InternalizeUtf8String("B"));
|
| + HUnique<String> C(factory->InternalizeUtf8String("C"));
|
| + HUnique<String> D(factory->InternalizeUtf8String("D"));
|
| + HUnique<String> E(factory->InternalizeUtf8String("E"));
|
| + HUnique<String> F(factory->InternalizeUtf8String("F"));
|
| + HUnique<String> G(factory->InternalizeUtf8String("G"));
|
| +
|
| + Zone zone(isolate);
|
| +
|
| + HUniqueSet<String>* set1 = new(&zone) HUniqueSet<String>();
|
| + HUniqueSet<String>* set2 = new(&zone) HUniqueSet<String>();
|
| +
|
| + set1->Add(A, &zone);
|
| + set1->Add(C, &zone);
|
| + set1->Add(E, &zone);
|
| +
|
| + set2->Add(A, &zone);
|
| + set2->Add(B, &zone);
|
| + set2->Add(C, &zone);
|
| + set2->Add(D, &zone);
|
| + set2->Add(E, &zone);
|
| + set2->Add(F, &zone);
|
| +
|
| + CHECK(set1->IsSubset(set2));
|
| + CHECK(!set2->IsSubset(set1));
|
| +
|
| + set1->Add(G, &zone);
|
| +
|
| + CHECK(!set1->IsSubset(set2));
|
| + CHECK(!set2->IsSubset(set1));
|
| +}
|
| +
|
| +
|
| +template <class T>
|
| +static HUniqueSet<T>* MakeSet(Zone* zone, int which, HUnique<T>* elements) {
|
| + HUniqueSet<T>* set = new(zone) HUniqueSet<T>();
|
| + for (int i = 0; i < 32; i++) {
|
| + if ((which & (1 << i)) != 0) set->Add(elements[i], zone);
|
| + }
|
| + return set;
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSet_IsSubsetExhaustive) {
|
| + const int kSetSize = 6;
|
| +
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + Zone zone(isolate);
|
| +
|
| + HUnique<String> A(factory->InternalizeUtf8String("A"));
|
| + HUnique<String> B(factory->InternalizeUtf8String("B"));
|
| + HUnique<String> C(factory->InternalizeUtf8String("C"));
|
| + HUnique<String> D(factory->InternalizeUtf8String("D"));
|
| + HUnique<String> E(factory->InternalizeUtf8String("E"));
|
| + HUnique<String> F(factory->InternalizeUtf8String("F"));
|
| + HUnique<String> G(factory->InternalizeUtf8String("G"));
|
| +
|
| + HUnique<String> elements[] = {
|
| + A, B, C, D, E, F, G
|
| + };
|
| +
|
| + // Exhaustively test all sets with <= 6 elements.
|
| + for (int i = 0; i < (1 << kSetSize); i++) {
|
| + for (int j = 0; j < (1 << kSetSize); j++) {
|
| + HUniqueSet<String>* set1 = MakeSet(&zone, i, elements);
|
| + HUniqueSet<String>* set2 = MakeSet(&zone, j, elements);
|
| +
|
| + CHECK(((i & j) == i) == set1->IsSubset(set2));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSet_Intersect1) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + HUnique<String> A(factory->InternalizeUtf8String("A"));
|
| + HUnique<String> B(factory->InternalizeUtf8String("B"));
|
| + HUnique<String> C(factory->InternalizeUtf8String("C"));
|
| +
|
| + Zone zone(isolate);
|
| +
|
| + HUniqueSet<String>* set1 = new(&zone) HUniqueSet<String>();
|
| + HUniqueSet<String>* set2 = new(&zone) HUniqueSet<String>();
|
| + HUniqueSet<String>* result;
|
| +
|
| + CHECK(set1->IsSubset(set2));
|
| + CHECK(set2->IsSubset(set1));
|
| +
|
| + set1->Add(A, &zone);
|
| +
|
| + result = set1->Intersect(set2, &zone);
|
| +
|
| + CHECK_EQ(0, result->size());
|
| + CHECK(set2->Equals(result));
|
| +
|
| + set2->Add(A, &zone);
|
| +
|
| + result = set1->Intersect(set2, &zone);
|
| +
|
| + CHECK_EQ(1, result->size());
|
| + CHECK(set1->Equals(result));
|
| + CHECK(set2->Equals(result));
|
| +
|
| + set2->Add(B, &zone);
|
| + set2->Add(C, &zone);
|
| +
|
| + result = set1->Intersect(set2, &zone);
|
| +
|
| + CHECK_EQ(1, result->size());
|
| + CHECK(set1->Equals(result));
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSet_IntersectExhaustive) {
|
| + const int kSetSize = 6;
|
| +
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + Zone zone(isolate);
|
| +
|
| + HUnique<String> A(factory->InternalizeUtf8String("A"));
|
| + HUnique<String> B(factory->InternalizeUtf8String("B"));
|
| + HUnique<String> C(factory->InternalizeUtf8String("C"));
|
| + HUnique<String> D(factory->InternalizeUtf8String("D"));
|
| + HUnique<String> E(factory->InternalizeUtf8String("E"));
|
| + HUnique<String> F(factory->InternalizeUtf8String("F"));
|
| + HUnique<String> G(factory->InternalizeUtf8String("G"));
|
| +
|
| + HUnique<String> elements[] = {
|
| + A, B, C, D, E, F, G
|
| + };
|
| +
|
| + // Exhaustively test all sets with <= 6 elements.
|
| + for (int i = 0; i < (1 << kSetSize); i++) {
|
| + for (int j = 0; j < (1 << kSetSize); j++) {
|
| + HUniqueSet<String>* set1 = MakeSet(&zone, i, elements);
|
| + HUniqueSet<String>* set2 = MakeSet(&zone, j, elements);
|
| +
|
| + HUniqueSet<String>* result = set1->Intersect(set2, &zone);
|
| + HUniqueSet<String>* expected = MakeSet(&zone, i & j, elements);
|
| +
|
| + CHECK(result->Equals(expected));
|
| + CHECK(expected->Equals(result));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSet_Union1) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + HUnique<String> A(factory->InternalizeUtf8String("A"));
|
| + HUnique<String> B(factory->InternalizeUtf8String("B"));
|
| + HUnique<String> C(factory->InternalizeUtf8String("C"));
|
| +
|
| + Zone zone(isolate);
|
| +
|
| + HUniqueSet<String>* set1 = new(&zone) HUniqueSet<String>();
|
| + HUniqueSet<String>* set2 = new(&zone) HUniqueSet<String>();
|
| + HUniqueSet<String>* result;
|
| +
|
| + CHECK(set1->IsSubset(set2));
|
| + CHECK(set2->IsSubset(set1));
|
| +
|
| + set1->Add(A, &zone);
|
| +
|
| + result = set1->Union(set2, &zone);
|
| +
|
| + CHECK_EQ(1, result->size());
|
| + CHECK(set1->Equals(result));
|
| +
|
| + set2->Add(A, &zone);
|
| +
|
| + result = set1->Union(set2, &zone);
|
| +
|
| + CHECK_EQ(1, result->size());
|
| + CHECK(set1->Equals(result));
|
| + CHECK(set2->Equals(result));
|
| +
|
| + set2->Add(B, &zone);
|
| + set2->Add(C, &zone);
|
| +
|
| + result = set1->Union(set2, &zone);
|
| +
|
| + CHECK_EQ(3, result->size());
|
| + CHECK(set2->Equals(result));
|
| +}
|
| +
|
| +
|
| +TEST(HUniqueSet_UnionExhaustive) {
|
| + const int kSetSize = 6;
|
| +
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + HandleScope sc(isolate);
|
| +
|
| + Zone zone(isolate);
|
| +
|
| + HUnique<String> A(factory->InternalizeUtf8String("A"));
|
| + HUnique<String> B(factory->InternalizeUtf8String("B"));
|
| + HUnique<String> C(factory->InternalizeUtf8String("C"));
|
| + HUnique<String> D(factory->InternalizeUtf8String("D"));
|
| + HUnique<String> E(factory->InternalizeUtf8String("E"));
|
| + HUnique<String> F(factory->InternalizeUtf8String("F"));
|
| + HUnique<String> G(factory->InternalizeUtf8String("G"));
|
| +
|
| + HUnique<String> elements[] = {
|
| + A, B, C, D, E, F, G
|
| + };
|
| +
|
| + // Exhaustively test all sets with <= 6 elements.
|
| + for (int i = 0; i < (1 << kSetSize); i++) {
|
| + for (int j = 0; j < (1 << kSetSize); j++) {
|
| + HUniqueSet<String>* set1 = MakeSet(&zone, i, elements);
|
| + HUniqueSet<String>* set2 = MakeSet(&zone, j, elements);
|
| +
|
| + HUniqueSet<String>* result = set1->Union(set2, &zone);
|
| + HUniqueSet<String>* expected = MakeSet(&zone, i | j, elements);
|
| +
|
| + CHECK(result->Equals(expected));
|
| + CHECK(expected->Equals(result));
|
| + }
|
| + }
|
| +}
|
| +
|
|
|