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 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 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 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 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 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 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 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 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 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 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 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 206 EXPECT_TRUE(all_changes.Includes(can_trigger_gc)); 207 EXPECT_FALSE(all_changes.Includes(depends_on_gc)); 208 EXPECT_TRUE(all_dependencies.Includes(depends_on_gc)); 209 EXPECT_FALSE(all_dependencies.Includes(can_trigger_gc)); 210 } 211 212 TEST(SideEffectsTest, BitStrings) { 213 EXPECT_STREQ( 214 "|||||||", 215 SideEffects::None().ToString().c_str()); 216 EXPECT_STREQ( 217 "|GC|DFJISCBZL|DFJISCBZL|GC|DFJISCBZL|DFJISCBZL|", 218 SideEffects::All().ToString().c_str()); 219 EXPECT_STREQ( 220 "|||||DFJISCBZL|DFJISCBZL|", 221 SideEffects::AllWrites().ToString().c_str()); 222 EXPECT_STREQ( 223 "||DFJISCBZL|DFJISCBZL||||", 224 SideEffects::AllReads().ToString().c_str()); 225 EXPECT_STREQ( 226 "||||||L|", 227 SideEffects::FieldWriteOfType(DataType::Type::kReference, false).ToString().c_str()); 228 EXPECT_STREQ( 229 "||DFJISCBZL|DFJISCBZL||DFJISCBZL|DFJISCBZL|", 230 SideEffects::FieldWriteOfType(DataType::Type::kReference, true).ToString().c_str()); 231 EXPECT_STREQ( 232 "|||||Z||", 233 SideEffects::ArrayWriteOfType(DataType::Type::kBool).ToString().c_str()); 234 EXPECT_STREQ( 235 "|||||C||", 236 SideEffects::ArrayWriteOfType(DataType::Type::kUint16).ToString().c_str()); 237 EXPECT_STREQ( 238 "|||||S||", 239 SideEffects::ArrayWriteOfType(DataType::Type::kInt16).ToString().c_str()); 240 EXPECT_STREQ( 241 "|||B||||", 242 SideEffects::FieldReadOfType(DataType::Type::kInt8, false).ToString().c_str()); 243 EXPECT_STREQ( 244 "||D|||||", 245 SideEffects::ArrayReadOfType(DataType::Type::kFloat64).ToString().c_str()); 246 EXPECT_STREQ( 247 "||J|||||", 248 SideEffects::ArrayReadOfType(DataType::Type::kInt64).ToString().c_str()); 249 EXPECT_STREQ( 250 "||F|||||", 251 SideEffects::ArrayReadOfType(DataType::Type::kFloat32).ToString().c_str()); 252 EXPECT_STREQ( 253 "||I|||||", 254 SideEffects::ArrayReadOfType(DataType::Type::kInt32).ToString().c_str()); 255 SideEffects s = SideEffects::None(); 256 s = s.Union(SideEffects::FieldWriteOfType(DataType::Type::kUint16, /* is_volatile */ false)); 257 s = s.Union(SideEffects::FieldWriteOfType(DataType::Type::kInt64, /* is_volatile */ false)); 258 s = s.Union(SideEffects::ArrayWriteOfType(DataType::Type::kInt16)); 259 s = s.Union(SideEffects::FieldReadOfType(DataType::Type::kInt32, /* is_volatile */ false)); 260 s = s.Union(SideEffects::ArrayReadOfType(DataType::Type::kFloat32)); 261 s = s.Union(SideEffects::ArrayReadOfType(DataType::Type::kFloat64)); 262 EXPECT_STREQ("||DF|I||S|JC|", s.ToString().c_str()); 263 } 264 265 } // namespace art 266