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 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 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