testJitRValueAlloc.cpp (9737B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 */ 4 /* This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8 #include "jit/Snapshots.h" 9 10 #include "jsapi-tests/tests.h" 11 12 using namespace js; 13 using namespace js::jit; 14 15 // These tests are checking that all slots of the current architecture can all 16 // be encoded and decoded correctly. We iterate on all registers and on many 17 // fake stack locations (Fibonacci). 18 static RValueAllocation Read(const RValueAllocation& slot) { 19 CompactBufferWriter writer; 20 slot.write(writer); 21 22 // Call hash to run its assertions. 23 slot.hash(); 24 25 CompactBufferReader reader(writer); 26 return RValueAllocation::read(reader); 27 } 28 29 class Fibonacci { 30 class Iterator { 31 public: 32 // std::iterator traits. 33 using iterator_category = std::input_iterator_tag; 34 using value_type = int32_t; 35 using difference_type = int32_t; 36 using pointer = value_type*; 37 using reference = value_type&; 38 39 private: 40 uint32_t value_{}; 41 uint32_t last_{}; 42 43 Iterator() = default; 44 Iterator(value_type value, value_type last) : value_(value), last_(last) {} 45 46 friend class Fibonacci; 47 48 public: 49 Iterator& operator++() { 50 auto next = value_ + last_; 51 if (next <= static_cast<uint32_t>(INT32_MAX)) { 52 last_ = value_; 53 value_ = next; 54 } else { 55 *this = Iterator{}; 56 } 57 return *this; 58 } 59 60 bool operator==(const Iterator& other) const { 61 return value_ == other.value_ && last_ == other.last_; 62 } 63 64 bool operator!=(const Iterator& other) const { return !(*this == other); } 65 66 auto operator*() const { return static_cast<int32_t>(value_); } 67 }; 68 69 public: 70 auto begin() { return Iterator{0, 1}; } 71 72 auto end() { return Iterator{}; } 73 }; 74 75 BEGIN_TEST(testJitRValueAlloc_Double) { 76 RValueAllocation s; 77 for (uint32_t i = 0; i < FloatRegisters::Total; i++) { 78 s = RValueAllocation::Double(FloatRegister::FromCode(i)); 79 CHECK(s == Read(s)); 80 } 81 return true; 82 } 83 END_TEST(testJitRValueAlloc_Double) 84 85 BEGIN_TEST(testJitRValueAlloc_FloatReg) { 86 RValueAllocation s; 87 for (uint32_t i = 0; i < FloatRegisters::Total; i++) { 88 s = RValueAllocation::Float32(FloatRegister::FromCode(i)); 89 CHECK(s == Read(s)); 90 } 91 return true; 92 } 93 END_TEST(testJitRValueAlloc_FloatReg) 94 95 BEGIN_TEST(testJitRValueAlloc_FloatStack) { 96 RValueAllocation s; 97 for (auto i : Fibonacci{}) { 98 s = RValueAllocation::Float32(i); 99 CHECK(s == Read(s)); 100 } 101 return true; 102 } 103 END_TEST(testJitRValueAlloc_FloatStack) 104 105 BEGIN_TEST(testJitRValueAlloc_TypedReg) { 106 RValueAllocation s; 107 for (uint32_t i = 0; i < Registers::Total; i++) { 108 #define FOR_EACH_JSVAL(_) \ 109 /* _(JSVAL_TYPE_DOUBLE) */ \ 110 _(JSVAL_TYPE_INT32) \ 111 /* _(JSVAL_TYPE_UNDEFINED) */ \ 112 _(JSVAL_TYPE_BOOLEAN) \ 113 /* _(JSVAL_TYPE_MAGIC) */ \ 114 _(JSVAL_TYPE_STRING) \ 115 _(JSVAL_TYPE_SYMBOL) \ 116 _(JSVAL_TYPE_BIGINT) \ 117 /* _(JSVAL_TYPE_NULL) */ \ 118 _(JSVAL_TYPE_OBJECT) 119 120 #define CHECK_WITH_JSVAL(jsval) \ 121 s = RValueAllocation::Typed(jsval, Register::FromCode(i)); \ 122 CHECK(s == Read(s)); 123 124 FOR_EACH_JSVAL(CHECK_WITH_JSVAL) 125 #undef CHECK_WITH_JSVAL 126 #undef FOR_EACH_JSVAL 127 } 128 return true; 129 } 130 END_TEST(testJitRValueAlloc_TypedReg) 131 132 BEGIN_TEST(testJitRValueAlloc_TypedStack) { 133 RValueAllocation s; 134 for (auto i : Fibonacci{}) { 135 #define FOR_EACH_JSVAL(_) \ 136 _(JSVAL_TYPE_DOUBLE) \ 137 _(JSVAL_TYPE_INT32) \ 138 /* _(JSVAL_TYPE_UNDEFINED) */ \ 139 _(JSVAL_TYPE_BOOLEAN) \ 140 /* _(JSVAL_TYPE_MAGIC) */ \ 141 _(JSVAL_TYPE_STRING) \ 142 _(JSVAL_TYPE_SYMBOL) \ 143 _(JSVAL_TYPE_BIGINT) \ 144 /* _(JSVAL_TYPE_NULL) */ \ 145 _(JSVAL_TYPE_OBJECT) 146 147 #define CHECK_WITH_JSVAL(jsval) \ 148 s = RValueAllocation::Typed(jsval, i); \ 149 CHECK(s == Read(s)); 150 151 FOR_EACH_JSVAL(CHECK_WITH_JSVAL) 152 #undef CHECK_WITH_JSVAL 153 #undef FOR_EACH_JSVAL 154 } 155 return true; 156 } 157 END_TEST(testJitRValueAlloc_TypedStack) 158 159 #if defined(JS_NUNBOX32) 160 161 BEGIN_TEST(testJitRValueAlloc_UntypedRegReg) { 162 RValueAllocation s; 163 for (uint32_t i = 0; i < Registers::Total; i++) { 164 for (uint32_t j = 0; j < Registers::Total; j++) { 165 if (i == j) { 166 continue; 167 } 168 s = RValueAllocation::Untyped(Register::FromCode(i), 169 Register::FromCode(j)); 170 MOZ_ASSERT(s == Read(s)); 171 CHECK(s == Read(s)); 172 } 173 } 174 return true; 175 } 176 END_TEST(testJitRValueAlloc_UntypedRegReg) 177 178 BEGIN_TEST(testJitRValueAlloc_UntypedRegStack) { 179 RValueAllocation s; 180 for (uint32_t i = 0; i < Registers::Total; i++) { 181 for (auto j : Fibonacci{}) { 182 s = RValueAllocation::Untyped(Register::FromCode(i), j); 183 CHECK(s == Read(s)); 184 } 185 } 186 return true; 187 } 188 END_TEST(testJitRValueAlloc_UntypedRegStack) 189 190 BEGIN_TEST(testJitRValueAlloc_UntypedStackReg) { 191 RValueAllocation s; 192 for (auto i : Fibonacci{}) { 193 for (uint32_t j = 0; j < Registers::Total; j++) { 194 s = RValueAllocation::Untyped(i, Register::FromCode(j)); 195 CHECK(s == Read(s)); 196 } 197 } 198 return true; 199 } 200 END_TEST(testJitRValueAlloc_UntypedStackReg) 201 202 BEGIN_TEST(testJitRValueAlloc_UntypedStackStack) { 203 RValueAllocation s; 204 for (auto i : Fibonacci{}) { 205 for (auto j : Fibonacci{}) { 206 s = RValueAllocation::Untyped(i, j); 207 CHECK(s == Read(s)); 208 } 209 } 210 return true; 211 } 212 END_TEST(testJitRValueAlloc_UntypedStackStack) 213 214 #else 215 216 BEGIN_TEST(testJitRValueAlloc_UntypedReg) { 217 RValueAllocation s; 218 for (uint32_t i = 0; i < Registers::Total; i++) { 219 s = RValueAllocation::Untyped(Register::FromCode(i)); 220 CHECK(s == Read(s)); 221 } 222 return true; 223 } 224 END_TEST(testJitRValueAlloc_UntypedReg) 225 226 BEGIN_TEST(testJitRValueAlloc_UntypedStack) { 227 RValueAllocation s; 228 for (auto i : Fibonacci{}) { 229 s = RValueAllocation::Untyped(i); 230 CHECK(s == Read(s)); 231 } 232 return true; 233 } 234 END_TEST(testJitRValueAlloc_UntypedStack) 235 236 #endif 237 238 BEGIN_TEST(testJitRValueAlloc_UndefinedAndNull) { 239 RValueAllocation s; 240 s = RValueAllocation::Undefined(); 241 CHECK(s == Read(s)); 242 s = RValueAllocation::Null(); 243 CHECK(s == Read(s)); 244 return true; 245 } 246 END_TEST(testJitRValueAlloc_UndefinedAndNull) 247 248 BEGIN_TEST(testJitRValueAlloc_ConstantPool) { 249 RValueAllocation s; 250 for (auto i : Fibonacci{}) { 251 s = RValueAllocation::ConstantPool(i); 252 CHECK(s == Read(s)); 253 } 254 return true; 255 } 256 END_TEST(testJitRValueAlloc_ConstantPool) 257 258 BEGIN_TEST(testJitRValueAlloc_Int64Cst) { 259 for (auto i : Fibonacci{}) { 260 for (auto j : Fibonacci{}) { 261 auto s = RValueAllocation::Int64Constant(i, j); 262 CHECK(s == Read(s)); 263 } 264 } 265 return true; 266 } 267 END_TEST(testJitRValueAlloc_Int64Cst) 268 269 #if defined(JS_NUNBOX32) 270 BEGIN_TEST(testJitRValueAlloc_Int64RegReg) { 271 RValueAllocation s; 272 for (uint32_t i = 0; i < Registers::Total; i++) { 273 for (uint32_t j = 0; j < Registers::Total; j++) { 274 if (i == j) { 275 continue; 276 } 277 s = RValueAllocation::Int64(Register::FromCode(i), Register::FromCode(j)); 278 MOZ_ASSERT(s == Read(s)); 279 CHECK(s == Read(s)); 280 } 281 } 282 return true; 283 } 284 END_TEST(testJitRValueAlloc_Int64RegReg) 285 286 BEGIN_TEST(testJitRValueAlloc_Int64RegStack) { 287 RValueAllocation s; 288 for (uint32_t i = 0; i < Registers::Total; i++) { 289 for (auto j : Fibonacci{}) { 290 s = RValueAllocation::Int64(Register::FromCode(i), j); 291 CHECK(s == Read(s)); 292 } 293 } 294 return true; 295 } 296 END_TEST(testJitRValueAlloc_Int64RegStack) 297 298 BEGIN_TEST(testJitRValueAlloc_Int64StackReg) { 299 RValueAllocation s; 300 for (auto i : Fibonacci{}) { 301 for (uint32_t j = 0; j < Registers::Total; j++) { 302 s = RValueAllocation::Int64(i, Register::FromCode(j)); 303 CHECK(s == Read(s)); 304 } 305 } 306 return true; 307 } 308 END_TEST(testJitRValueAlloc_Int64StackReg) 309 310 BEGIN_TEST(testJitRValueAlloc_Int64StackStack) { 311 RValueAllocation s; 312 for (auto i : Fibonacci{}) { 313 for (auto j : Fibonacci{}) { 314 s = RValueAllocation::Int64(i, j); 315 CHECK(s == Read(s)); 316 } 317 } 318 return true; 319 } 320 END_TEST(testJitRValueAlloc_Int64StackStack) 321 #else 322 BEGIN_TEST(testJitRValueAlloc_Int64Reg) { 323 for (uint32_t i = 0; i < Registers::Total; i++) { 324 auto s = RValueAllocation::Int64(Register::FromCode(i)); 325 CHECK(s == Read(s)); 326 } 327 return true; 328 } 329 END_TEST(testJitRValueAlloc_Int64Reg) 330 331 BEGIN_TEST(testJitRValueAlloc_Int64Stack) { 332 for (auto i : Fibonacci{}) { 333 auto s = RValueAllocation::Int64(i); 334 CHECK(s == Read(s)); 335 } 336 return true; 337 } 338 END_TEST(testJitRValueAlloc_Int64Stack) 339 #endif 340 341 BEGIN_TEST(testJitRValueAlloc_IntPtrCst) { 342 #if !defined(JS_64BIT) 343 for (auto i : Fibonacci{}) { 344 auto s = RValueAllocation::IntPtrConstant(i); 345 CHECK(s == Read(s)); 346 } 347 #else 348 for (auto i : Fibonacci{}) { 349 for (auto j : Fibonacci{}) { 350 auto s = RValueAllocation::IntPtrConstant(i, j); 351 CHECK(s == Read(s)); 352 } 353 } 354 #endif 355 return true; 356 } 357 END_TEST(testJitRValueAlloc_IntPtrCst) 358 359 BEGIN_TEST(testJitRValueAlloc_IntPtrReg) { 360 for (uint32_t i = 0; i < Registers::Total; i++) { 361 auto s = RValueAllocation::IntPtr(Register::FromCode(i)); 362 CHECK(s == Read(s)); 363 } 364 return true; 365 } 366 END_TEST(testJitRValueAlloc_IntPtrReg) 367 368 BEGIN_TEST(testJitRValueAlloc_IntPtrStack) { 369 for (auto i : Fibonacci{}) { 370 auto s = RValueAllocation::IntPtr(i); 371 CHECK(s == Read(s)); 372 } 373 return true; 374 } 375 END_TEST(testJitRValueAlloc_IntPtrStack) 376 377 BEGIN_TEST(testJitRValueAlloc_IntPtrInt32Stack) { 378 for (auto i : Fibonacci{}) { 379 auto s = RValueAllocation::IntPtrInt32(i); 380 CHECK(s == Read(s)); 381 } 382 return true; 383 } 384 END_TEST(testJitRValueAlloc_IntPtrInt32Stack)