blob: d9a6a45633d267f233eb26271b6cc2f164667347 [file] [log] [blame]
Brian Carlstrom7e93b502011-08-04 14:16:22 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include "intern_table.h"
4
5#include "common_test.h"
6#include "object.h"
7
Brian Carlstrom7e93b502011-08-04 14:16:22 -07008namespace art {
9
Brian Carlstromf734cf52011-08-17 16:28:14 -070010class InternTableTest : public CommonTest {};
Brian Carlstrom7e93b502011-08-04 14:16:22 -070011
12TEST_F(InternTableTest, Intern) {
13 InternTable intern_table;
Elliott Hughescf4c6c42011-09-01 15:16:42 -070014 const String* foo_1 = intern_table.InternStrong(3, "foo");
15 const String* foo_2 = intern_table.InternStrong(3, "foo");
16 const String* foo_3 = String::AllocFromModifiedUtf8("foo");
17 const String* bar = intern_table.InternStrong(3, "bar");
Brian Carlstrom7e93b502011-08-04 14:16:22 -070018 EXPECT_TRUE(foo_1->Equals("foo"));
19 EXPECT_TRUE(foo_2->Equals("foo"));
20 EXPECT_TRUE(foo_3->Equals("foo"));
21 EXPECT_TRUE(foo_1 != NULL);
22 EXPECT_TRUE(foo_2 != NULL);
23 EXPECT_EQ(foo_1, foo_2);
24 EXPECT_NE(foo_1, bar);
25 EXPECT_NE(foo_2, bar);
26 EXPECT_NE(foo_3, bar);
27}
28
Elliott Hughescf4c6c42011-09-01 15:16:42 -070029TEST_F(InternTableTest, Size) {
30 InternTable t;
31 EXPECT_EQ(0U, t.Size());
32 t.InternStrong(3, "foo");
33 t.InternWeak(String::AllocFromModifiedUtf8("foo"));
34 EXPECT_EQ(1U, t.Size());
35 t.InternStrong(3, "bar");
36 EXPECT_EQ(2U, t.Size());
37}
38
Elliott Hughesc33a32b2011-10-11 18:18:07 -070039class TestPredicate {
Elliott Hughes410c0c82011-09-01 17:58:25 -070040 public:
Elliott Hughesc33a32b2011-10-11 18:18:07 -070041 bool IsMarked(const Object* s) const {
Elliott Hughes410c0c82011-09-01 17:58:25 -070042 bool erased = false;
43 typedef std::vector<const String*>::iterator It; // TODO: C++0x auto
44 for (It it = expected_.begin(), end = expected_.end(); it != end; ++it) {
45 if (*it == s) {
46 expected_.erase(it);
47 erased = true;
48 break;
49 }
Elliott Hughescf4c6c42011-09-01 15:16:42 -070050 }
Elliott Hughes410c0c82011-09-01 17:58:25 -070051 EXPECT_TRUE(erased);
Elliott Hughesc33a32b2011-10-11 18:18:07 -070052 return false;
Elliott Hughescf4c6c42011-09-01 15:16:42 -070053 }
Elliott Hughes410c0c82011-09-01 17:58:25 -070054
55 void Expect(const String* s) {
56 expected_.push_back(s);
57 }
58
59 ~TestPredicate() {
60 EXPECT_EQ(0U, expected_.size());
61 }
62
63 private:
64 mutable std::vector<const String*> expected_;
65};
Elliott Hughescf4c6c42011-09-01 15:16:42 -070066
Elliott Hughesc33a32b2011-10-11 18:18:07 -070067bool IsMarked(const Object* object, void* arg) {
68 return reinterpret_cast<TestPredicate*>(arg)->IsMarked(object);
69}
70
71TEST_F(InternTableTest, SweepInternTableWeaks) {
Elliott Hughescf4c6c42011-09-01 15:16:42 -070072 InternTable t;
73 t.InternStrong(3, "foo");
74 t.InternStrong(3, "bar");
75 const String* s0 = t.InternWeak(String::AllocFromModifiedUtf8("hello"));
76 const String* s1 = t.InternWeak(String::AllocFromModifiedUtf8("world"));
77
78 EXPECT_EQ(4U, t.Size());
79
80 // We should traverse only the weaks...
Elliott Hughes410c0c82011-09-01 17:58:25 -070081 TestPredicate p;
82 p.Expect(s0);
83 p.Expect(s1);
Elliott Hughesc33a32b2011-10-11 18:18:07 -070084 t.SweepInternTableWeaks(IsMarked, &p);
Elliott Hughescf4c6c42011-09-01 15:16:42 -070085
86 EXPECT_EQ(2U, t.Size());
87
88 // Just check that we didn't corrupt the unordered_multimap.
89 t.InternWeak(String::AllocFromModifiedUtf8("still here"));
90 EXPECT_EQ(3U, t.Size());
91}
92
93TEST_F(InternTableTest, ContainsWeak) {
94 {
95 // Strongs are never weak.
96 InternTable t;
Brian Carlstromc74255f2011-09-11 22:47:39 -070097 String* foo_1 = t.InternStrong(3, "foo");
Elliott Hughescf4c6c42011-09-01 15:16:42 -070098 EXPECT_FALSE(t.ContainsWeak(foo_1));
Brian Carlstromc74255f2011-09-11 22:47:39 -070099 String* foo_2 = t.InternStrong(3, "foo");
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700100 EXPECT_FALSE(t.ContainsWeak(foo_2));
101 EXPECT_EQ(foo_1, foo_2);
102 }
103
104 {
105 // Weaks are always weak.
106 InternTable t;
Brian Carlstromc74255f2011-09-11 22:47:39 -0700107 String* foo_1 = t.InternWeak(String::AllocFromModifiedUtf8("foo"));
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700108 EXPECT_TRUE(t.ContainsWeak(foo_1));
Brian Carlstromc74255f2011-09-11 22:47:39 -0700109 String* foo_2 = t.InternWeak(String::AllocFromModifiedUtf8("foo"));
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700110 EXPECT_TRUE(t.ContainsWeak(foo_2));
111 EXPECT_EQ(foo_1, foo_2);
112 }
113
114 {
115 // A weak can be promoted to a strong.
116 InternTable t;
Brian Carlstromc74255f2011-09-11 22:47:39 -0700117 String* foo_1 = t.InternWeak(String::AllocFromModifiedUtf8("foo"));
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700118 EXPECT_TRUE(t.ContainsWeak(foo_1));
Brian Carlstromc74255f2011-09-11 22:47:39 -0700119 String* foo_2 = t.InternStrong(3, "foo");
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700120 EXPECT_FALSE(t.ContainsWeak(foo_2));
121 EXPECT_EQ(foo_1, foo_2);
122 }
123
124 {
125 // Interning a weak after a strong gets you the strong.
126 InternTable t;
Brian Carlstromc74255f2011-09-11 22:47:39 -0700127 String* foo_1 = t.InternStrong(3, "foo");
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700128 EXPECT_FALSE(t.ContainsWeak(foo_1));
Brian Carlstromc74255f2011-09-11 22:47:39 -0700129 String* foo_2 = t.InternWeak(String::AllocFromModifiedUtf8("foo"));
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700130 EXPECT_FALSE(t.ContainsWeak(foo_2));
131 EXPECT_EQ(foo_1, foo_2);
132 }
133}
134
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700135} // namespace art