blob: 52531cee32b3da6d33cc26dddf148c8e9e5cc7e6 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian Carlstrom7e93b502011-08-04 14:16:22 -070016
17#include "intern_table.h"
18
19#include "common_test.h"
20#include "object.h"
21
Brian Carlstrom7e93b502011-08-04 14:16:22 -070022namespace art {
23
Brian Carlstromf734cf52011-08-17 16:28:14 -070024class InternTableTest : public CommonTest {};
Brian Carlstrom7e93b502011-08-04 14:16:22 -070025
26TEST_F(InternTableTest, Intern) {
27 InternTable intern_table;
Brian Carlstrom40381fb2011-10-19 14:13:40 -070028 SirtRef<String> foo_1(intern_table.InternStrong(3, "foo"));
29 SirtRef<String> foo_2(intern_table.InternStrong(3, "foo"));
30 SirtRef<String> foo_3(String::AllocFromModifiedUtf8("foo"));
31 SirtRef<String> bar(intern_table.InternStrong(3, "bar"));
Brian Carlstrom7e93b502011-08-04 14:16:22 -070032 EXPECT_TRUE(foo_1->Equals("foo"));
33 EXPECT_TRUE(foo_2->Equals("foo"));
34 EXPECT_TRUE(foo_3->Equals("foo"));
Brian Carlstrom40381fb2011-10-19 14:13:40 -070035 EXPECT_TRUE(foo_1.get() != NULL);
36 EXPECT_TRUE(foo_2.get() != NULL);
37 EXPECT_EQ(foo_1.get(), foo_2.get());
38 EXPECT_NE(foo_1.get(), bar.get());
39 EXPECT_NE(foo_2.get(), bar.get());
40 EXPECT_NE(foo_3.get(), bar.get());
Brian Carlstrom7e93b502011-08-04 14:16:22 -070041}
42
Elliott Hughescf4c6c42011-09-01 15:16:42 -070043TEST_F(InternTableTest, Size) {
44 InternTable t;
45 EXPECT_EQ(0U, t.Size());
46 t.InternStrong(3, "foo");
Brian Carlstrom40381fb2011-10-19 14:13:40 -070047 SirtRef<String> foo(String::AllocFromModifiedUtf8("foo"));
48 t.InternWeak(foo.get());
Elliott Hughescf4c6c42011-09-01 15:16:42 -070049 EXPECT_EQ(1U, t.Size());
50 t.InternStrong(3, "bar");
51 EXPECT_EQ(2U, t.Size());
52}
53
Elliott Hughesc33a32b2011-10-11 18:18:07 -070054class TestPredicate {
Elliott Hughes410c0c82011-09-01 17:58:25 -070055 public:
Elliott Hughesc33a32b2011-10-11 18:18:07 -070056 bool IsMarked(const Object* s) const {
Elliott Hughes410c0c82011-09-01 17:58:25 -070057 bool erased = false;
58 typedef std::vector<const String*>::iterator It; // TODO: C++0x auto
59 for (It it = expected_.begin(), end = expected_.end(); it != end; ++it) {
60 if (*it == s) {
61 expected_.erase(it);
62 erased = true;
63 break;
64 }
Elliott Hughescf4c6c42011-09-01 15:16:42 -070065 }
Elliott Hughes410c0c82011-09-01 17:58:25 -070066 EXPECT_TRUE(erased);
Elliott Hughesc33a32b2011-10-11 18:18:07 -070067 return false;
Elliott Hughescf4c6c42011-09-01 15:16:42 -070068 }
Elliott Hughes410c0c82011-09-01 17:58:25 -070069
70 void Expect(const String* s) {
71 expected_.push_back(s);
72 }
73
74 ~TestPredicate() {
75 EXPECT_EQ(0U, expected_.size());
76 }
77
78 private:
79 mutable std::vector<const String*> expected_;
80};
Elliott Hughescf4c6c42011-09-01 15:16:42 -070081
Elliott Hughesc33a32b2011-10-11 18:18:07 -070082bool IsMarked(const Object* object, void* arg) {
83 return reinterpret_cast<TestPredicate*>(arg)->IsMarked(object);
84}
85
86TEST_F(InternTableTest, SweepInternTableWeaks) {
Elliott Hughescf4c6c42011-09-01 15:16:42 -070087 InternTable t;
88 t.InternStrong(3, "foo");
89 t.InternStrong(3, "bar");
Brian Carlstrom40381fb2011-10-19 14:13:40 -070090 SirtRef<String> hello(String::AllocFromModifiedUtf8("hello"));
91 SirtRef<String> world(String::AllocFromModifiedUtf8("world"));
92 SirtRef<String> s0(t.InternWeak(hello.get()));
93 SirtRef<String> s1(t.InternWeak(world.get()));
Elliott Hughescf4c6c42011-09-01 15:16:42 -070094
95 EXPECT_EQ(4U, t.Size());
96
97 // We should traverse only the weaks...
Elliott Hughes410c0c82011-09-01 17:58:25 -070098 TestPredicate p;
Brian Carlstrom40381fb2011-10-19 14:13:40 -070099 p.Expect(s0.get());
100 p.Expect(s1.get());
Elliott Hughesc33a32b2011-10-11 18:18:07 -0700101 t.SweepInternTableWeaks(IsMarked, &p);
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700102
103 EXPECT_EQ(2U, t.Size());
104
Elliott Hughese5448b52012-01-18 16:44:06 -0800105 // Just check that we didn't corrupt the map.
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700106 SirtRef<String> still_here(String::AllocFromModifiedUtf8("still here"));
107 t.InternWeak(still_here.get());
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700108 EXPECT_EQ(3U, t.Size());
109}
110
111TEST_F(InternTableTest, ContainsWeak) {
112 {
113 // Strongs are never weak.
114 InternTable t;
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700115 SirtRef<String> interned_foo_1(t.InternStrong(3, "foo"));
116 EXPECT_FALSE(t.ContainsWeak(interned_foo_1.get()));
117 SirtRef<String> interned_foo_2(t.InternStrong(3, "foo"));
118 EXPECT_FALSE(t.ContainsWeak(interned_foo_2.get()));
119 EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get());
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700120 }
121
122 {
123 // Weaks are always weak.
124 InternTable t;
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700125 SirtRef<String> foo_1(String::AllocFromModifiedUtf8("foo"));
126 SirtRef<String> foo_2(String::AllocFromModifiedUtf8("foo"));
127 EXPECT_NE(foo_1.get(), foo_2.get());
128 SirtRef<String> interned_foo_1(t.InternWeak(foo_1.get()));
129 SirtRef<String> interned_foo_2(t.InternWeak(foo_2.get()));
130 EXPECT_TRUE(t.ContainsWeak(interned_foo_2.get()));
131 EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get());
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700132 }
133
134 {
135 // A weak can be promoted to a strong.
136 InternTable t;
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700137 SirtRef<String> foo(String::AllocFromModifiedUtf8("foo"));
138 SirtRef<String> interned_foo_1(t.InternWeak(foo.get()));
139 EXPECT_TRUE(t.ContainsWeak(interned_foo_1.get()));
140 SirtRef<String> interned_foo_2(t.InternStrong(3, "foo"));
141 EXPECT_FALSE(t.ContainsWeak(interned_foo_2.get()));
142 EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get());
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700143 }
144
145 {
146 // Interning a weak after a strong gets you the strong.
147 InternTable t;
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700148 SirtRef<String> interned_foo_1(t.InternStrong(3, "foo"));
149 EXPECT_FALSE(t.ContainsWeak(interned_foo_1.get()));
150 SirtRef<String> foo(String::AllocFromModifiedUtf8("foo"));
151 SirtRef<String> interned_foo_2(t.InternWeak(foo.get()));
152 EXPECT_FALSE(t.ContainsWeak(interned_foo_2.get()));
153 EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get());
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700154 }
155}
156
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700157} // namespace art