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