• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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