1 /*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not read 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 */
16
17 #include <gtest/gtest.h>
18
19 #include "base/macros.h"
20 #include "data_type.h"
21 #include "nodes.h"
22
23 namespace art HIDDEN {
24
25 // Only runtime types other than void are allowed.
26 static const DataType::Type kTestTypes[] = {
27 DataType::Type::kReference,
28 DataType::Type::kBool,
29 DataType::Type::kInt8,
30 DataType::Type::kUint16,
31 DataType::Type::kInt16,
32 DataType::Type::kInt32,
33 DataType::Type::kInt64,
34 DataType::Type::kFloat32,
35 DataType::Type::kFloat64,
36 };
37
38 /**
39 * Tests for the SideEffects class.
40 */
41
42 //
43 // Helper methods.
44 //
45
testWriteAndReadEffects(SideEffects write,SideEffects read)46 void testWriteAndReadEffects(SideEffects write, SideEffects read) {
47 EXPECT_FALSE(write.DoesNothing());
48 EXPECT_FALSE(read.DoesNothing());
49
50 EXPECT_TRUE(write.DoesAnyWrite());
51 EXPECT_FALSE(write.DoesAnyRead());
52 EXPECT_FALSE(read.DoesAnyWrite());
53 EXPECT_TRUE(read.DoesAnyRead());
54
55 // All-dependences.
56 SideEffects all = SideEffects::All();
57 EXPECT_TRUE(all.MayDependOn(write));
58 EXPECT_FALSE(write.MayDependOn(all));
59 EXPECT_FALSE(all.MayDependOn(read));
60 EXPECT_TRUE(read.MayDependOn(all));
61
62 // None-dependences.
63 SideEffects none = SideEffects::None();
64 EXPECT_FALSE(none.MayDependOn(write));
65 EXPECT_FALSE(write.MayDependOn(none));
66 EXPECT_FALSE(none.MayDependOn(read));
67 EXPECT_FALSE(read.MayDependOn(none));
68 }
69
testWriteAndReadDependence(SideEffects write,SideEffects read)70 void testWriteAndReadDependence(SideEffects write, SideEffects read) {
71 testWriteAndReadEffects(write, read);
72
73 // Dependence only in one direction.
74 EXPECT_FALSE(write.MayDependOn(read));
75 EXPECT_TRUE(read.MayDependOn(write));
76 }
77
testNoWriteAndReadDependence(SideEffects write,SideEffects read)78 void testNoWriteAndReadDependence(SideEffects write, SideEffects read) {
79 testWriteAndReadEffects(write, read);
80
81 // No dependence in any direction.
82 EXPECT_FALSE(write.MayDependOn(read));
83 EXPECT_FALSE(read.MayDependOn(write));
84 }
85
86 //
87 // Actual tests.
88 //
89
TEST(SideEffectsTest,All)90 TEST(SideEffectsTest, All) {
91 SideEffects all = SideEffects::All();
92 EXPECT_TRUE(all.DoesAnyWrite());
93 EXPECT_TRUE(all.DoesAnyRead());
94 EXPECT_FALSE(all.DoesNothing());
95 EXPECT_TRUE(all.DoesAllReadWrite());
96 }
97
TEST(SideEffectsTest,None)98 TEST(SideEffectsTest, None) {
99 SideEffects none = SideEffects::None();
100 EXPECT_FALSE(none.DoesAnyWrite());
101 EXPECT_FALSE(none.DoesAnyRead());
102 EXPECT_TRUE(none.DoesNothing());
103 EXPECT_FALSE(none.DoesAllReadWrite());
104 }
105
TEST(SideEffectsTest,DependencesAndNoDependences)106 TEST(SideEffectsTest, DependencesAndNoDependences) {
107 // Apply test to each individual data type.
108 for (DataType::Type type : kTestTypes) {
109 // Same data type and access type: proper write/read dep.
110 testWriteAndReadDependence(
111 SideEffects::FieldWriteOfType(type, false),
112 SideEffects::FieldReadOfType(type, false));
113 testWriteAndReadDependence(
114 SideEffects::ArrayWriteOfType(type),
115 SideEffects::ArrayReadOfType(type));
116 // Same data type but different access type: no write/read dep.
117 testNoWriteAndReadDependence(
118 SideEffects::FieldWriteOfType(type, false),
119 SideEffects::ArrayReadOfType(type));
120 testNoWriteAndReadDependence(
121 SideEffects::ArrayWriteOfType(type),
122 SideEffects::FieldReadOfType(type, false));
123 }
124 }
125
TEST(SideEffectsTest,NoDependences)126 TEST(SideEffectsTest, NoDependences) {
127 // Different data type, same access type: no write/read dep.
128 testNoWriteAndReadDependence(
129 SideEffects::FieldWriteOfType(DataType::Type::kInt32, false),
130 SideEffects::FieldReadOfType(DataType::Type::kFloat64, false));
131 testNoWriteAndReadDependence(
132 SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
133 SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
134 // Everything different: no write/read dep.
135 testNoWriteAndReadDependence(
136 SideEffects::FieldWriteOfType(DataType::Type::kInt32, false),
137 SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
138 testNoWriteAndReadDependence(
139 SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
140 SideEffects::FieldReadOfType(DataType::Type::kFloat64, false));
141 }
142
TEST(SideEffectsTest,VolatileDependences)143 TEST(SideEffectsTest, VolatileDependences) {
144 SideEffects volatile_write =
145 SideEffects::FieldWriteOfType(DataType::Type::kInt32, /* is_volatile= */ true);
146 SideEffects any_write =
147 SideEffects::FieldWriteOfType(DataType::Type::kInt32, /* is_volatile= */ false);
148 SideEffects volatile_read =
149 SideEffects::FieldReadOfType(DataType::Type::kInt8, /* is_volatile= */ true);
150 SideEffects any_read =
151 SideEffects::FieldReadOfType(DataType::Type::kInt8, /* is_volatile= */ false);
152
153 EXPECT_FALSE(volatile_write.MayDependOn(any_read));
154 EXPECT_TRUE(any_read.MayDependOn(volatile_write));
155 EXPECT_TRUE(volatile_write.MayDependOn(any_write));
156 EXPECT_FALSE(any_write.MayDependOn(volatile_write));
157
158 EXPECT_FALSE(volatile_read.MayDependOn(any_read));
159 EXPECT_TRUE(any_read.MayDependOn(volatile_read));
160 EXPECT_TRUE(volatile_read.MayDependOn(any_write));
161 EXPECT_FALSE(any_write.MayDependOn(volatile_read));
162 }
163
TEST(SideEffectsTest,SameWidthTypesNoAlias)164 TEST(SideEffectsTest, SameWidthTypesNoAlias) {
165 // Type I/F.
166 testNoWriteAndReadDependence(
167 SideEffects::FieldWriteOfType(DataType::Type::kInt32, /* is_volatile= */ false),
168 SideEffects::FieldReadOfType(DataType::Type::kFloat32, /* is_volatile= */ false));
169 testNoWriteAndReadDependence(
170 SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
171 SideEffects::ArrayReadOfType(DataType::Type::kFloat32));
172 // Type L/D.
173 testNoWriteAndReadDependence(
174 SideEffects::FieldWriteOfType(DataType::Type::kInt64, /* is_volatile= */ false),
175 SideEffects::FieldReadOfType(DataType::Type::kFloat64, /* is_volatile= */ false));
176 testNoWriteAndReadDependence(
177 SideEffects::ArrayWriteOfType(DataType::Type::kInt64),
178 SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
179 }
180
TEST(SideEffectsTest,AllWritesAndReads)181 TEST(SideEffectsTest, AllWritesAndReads) {
182 SideEffects s = SideEffects::None();
183 // Keep taking the union of different writes and reads.
184 for (DataType::Type type : kTestTypes) {
185 s = s.Union(SideEffects::FieldWriteOfType(type, /* is_volatile= */ false));
186 s = s.Union(SideEffects::ArrayWriteOfType(type));
187 s = s.Union(SideEffects::FieldReadOfType(type, /* is_volatile= */ false));
188 s = s.Union(SideEffects::ArrayReadOfType(type));
189 }
190 EXPECT_TRUE(s.DoesAllReadWrite());
191 }
192
TEST(SideEffectsTest,GC)193 TEST(SideEffectsTest, GC) {
194 SideEffects can_trigger_gc = SideEffects::CanTriggerGC();
195 SideEffects depends_on_gc = SideEffects::DependsOnGC();
196 SideEffects all_changes = SideEffects::AllChanges();
197 SideEffects all_dependencies = SideEffects::AllDependencies();
198
199 EXPECT_TRUE(depends_on_gc.MayDependOn(can_trigger_gc));
200 EXPECT_TRUE(depends_on_gc.Union(can_trigger_gc).MayDependOn(can_trigger_gc));
201 EXPECT_FALSE(can_trigger_gc.MayDependOn(depends_on_gc));
202
203 EXPECT_TRUE(depends_on_gc.MayDependOn(all_changes));
204 EXPECT_TRUE(depends_on_gc.Union(can_trigger_gc).MayDependOn(all_changes));
205 EXPECT_FALSE(can_trigger_gc.MayDependOn(all_changes));
206 EXPECT_FALSE(can_trigger_gc.MayDependOn(can_trigger_gc));
207
208 EXPECT_TRUE(all_changes.Includes(can_trigger_gc));
209 EXPECT_FALSE(all_changes.Includes(depends_on_gc));
210 EXPECT_TRUE(all_dependencies.Includes(depends_on_gc));
211 EXPECT_FALSE(all_dependencies.Includes(can_trigger_gc));
212 }
213
TEST(SideEffectsTest,BitStrings)214 TEST(SideEffectsTest, BitStrings) {
215 EXPECT_STREQ(
216 "|||||||",
217 SideEffects::None().ToString().c_str());
218 EXPECT_STREQ(
219 "|GC|DFJISCBZL|DFJISCBZL|GC|DFJISCBZL|DFJISCBZL|",
220 SideEffects::All().ToString().c_str());
221 EXPECT_STREQ(
222 "|||||DFJISCBZL|DFJISCBZL|",
223 SideEffects::AllWrites().ToString().c_str());
224 EXPECT_STREQ(
225 "||DFJISCBZL|DFJISCBZL||||",
226 SideEffects::AllReads().ToString().c_str());
227 EXPECT_STREQ(
228 "||||||L|",
229 SideEffects::FieldWriteOfType(DataType::Type::kReference, false).ToString().c_str());
230 EXPECT_STREQ(
231 "||DFJISCBZL|DFJISCBZL||DFJISCBZL|DFJISCBZL|",
232 SideEffects::FieldWriteOfType(DataType::Type::kReference, true).ToString().c_str());
233 EXPECT_STREQ(
234 "|||||Z||",
235 SideEffects::ArrayWriteOfType(DataType::Type::kBool).ToString().c_str());
236 EXPECT_STREQ(
237 "|||||C||",
238 SideEffects::ArrayWriteOfType(DataType::Type::kUint16).ToString().c_str());
239 EXPECT_STREQ(
240 "|||||S||",
241 SideEffects::ArrayWriteOfType(DataType::Type::kInt16).ToString().c_str());
242 EXPECT_STREQ(
243 "|||B||||",
244 SideEffects::FieldReadOfType(DataType::Type::kInt8, false).ToString().c_str());
245 EXPECT_STREQ(
246 "||D|||||",
247 SideEffects::ArrayReadOfType(DataType::Type::kFloat64).ToString().c_str());
248 EXPECT_STREQ(
249 "||J|||||",
250 SideEffects::ArrayReadOfType(DataType::Type::kInt64).ToString().c_str());
251 EXPECT_STREQ(
252 "||F|||||",
253 SideEffects::ArrayReadOfType(DataType::Type::kFloat32).ToString().c_str());
254 EXPECT_STREQ(
255 "||I|||||",
256 SideEffects::ArrayReadOfType(DataType::Type::kInt32).ToString().c_str());
257 SideEffects s = SideEffects::None();
258 s = s.Union(SideEffects::FieldWriteOfType(DataType::Type::kUint16, /* is_volatile= */ false));
259 s = s.Union(SideEffects::FieldWriteOfType(DataType::Type::kInt64, /* is_volatile= */ false));
260 s = s.Union(SideEffects::ArrayWriteOfType(DataType::Type::kInt16));
261 s = s.Union(SideEffects::FieldReadOfType(DataType::Type::kInt32, /* is_volatile= */ false));
262 s = s.Union(SideEffects::ArrayReadOfType(DataType::Type::kFloat32));
263 s = s.Union(SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
264 EXPECT_STREQ("||DF|I||S|JC|", s.ToString().c_str());
265 }
266
267 } // namespace art
268