OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits> | 5 #include <limits> |
6 | 6 |
7 #include "src/compiler/control-builders.h" | 7 #include "src/compiler/control-builders.h" |
8 #include "src/compiler/generic-node-inl.h" | 8 #include "src/compiler/generic-node-inl.h" |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 | 135 |
136 | 136 |
137 TEST(RunLoadMap) { | 137 TEST(RunLoadMap) { |
138 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); | 138 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); |
139 FieldAccess access = ForJSObjectMap(); | 139 FieldAccess access = ForJSObjectMap(); |
140 Node* load = t.LoadField(access, t.Parameter(0)); | 140 Node* load = t.LoadField(access, t.Parameter(0)); |
141 t.Return(load); | 141 t.Return(load); |
142 | 142 |
143 t.LowerAllNodes(); | 143 t.LowerAllNodes(); |
144 | 144 |
145 if (!Pipeline::SupportedTarget()) return; | 145 if (Pipeline::SupportedTarget()) { |
146 | 146 t.GenerateCode(); |
147 Handle<JSObject> src = TestObject(); | 147 Handle<JSObject> src = TestObject(); |
148 Handle<Map> src_map(src->map()); | 148 Handle<Map> src_map(src->map()); |
149 Object* result = t.Call(*src); | 149 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
150 CHECK_EQ(*src_map, result); | 150 CHECK_EQ(*src_map, result); |
| 151 } |
151 } | 152 } |
152 | 153 |
153 | 154 |
154 TEST(RunStoreMap) { | 155 TEST(RunStoreMap) { |
155 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged, kMachineTagged); | 156 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged, kMachineTagged); |
156 FieldAccess access = ForJSObjectMap(); | 157 FieldAccess access = ForJSObjectMap(); |
157 t.StoreField(access, t.Parameter(1), t.Parameter(0)); | 158 t.StoreField(access, t.Parameter(1), t.Parameter(0)); |
158 t.Return(t.Int32Constant(0)); | 159 t.Return(t.jsgraph.TrueConstant()); |
159 | 160 |
160 t.LowerAllNodes(); | 161 t.LowerAllNodes(); |
161 | 162 |
162 if (!Pipeline::SupportedTarget()) return; | 163 if (Pipeline::SupportedTarget()) { |
163 | 164 t.GenerateCode(); |
164 Handle<JSObject> src = TestObject(); | 165 Handle<JSObject> src = TestObject(); |
165 Handle<Map> src_map(src->map()); | 166 Handle<Map> src_map(src->map()); |
166 Handle<JSObject> dst = TestObject(); | 167 Handle<JSObject> dst = TestObject(); |
167 CHECK(src->map() != dst->map()); | 168 CHECK(src->map() != dst->map()); |
168 t.Call(*src_map, *dst); | 169 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call |
169 CHECK(*src_map == dst->map()); | 170 CHECK(*src_map == dst->map()); |
| 171 } |
170 } | 172 } |
171 | 173 |
172 | 174 |
173 TEST(RunLoadProperties) { | 175 TEST(RunLoadProperties) { |
174 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); | 176 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); |
175 FieldAccess access = ForJSObjectProperties(); | 177 FieldAccess access = ForJSObjectProperties(); |
176 Node* load = t.LoadField(access, t.Parameter(0)); | 178 Node* load = t.LoadField(access, t.Parameter(0)); |
177 t.Return(load); | 179 t.Return(load); |
178 | 180 |
179 t.LowerAllNodes(); | 181 t.LowerAllNodes(); |
180 | 182 |
181 if (!Pipeline::SupportedTarget()) return; | 183 if (Pipeline::SupportedTarget()) { |
182 | 184 t.GenerateCode(); |
183 Handle<JSObject> src = TestObject(); | 185 Handle<JSObject> src = TestObject(); |
184 Handle<FixedArray> src_props(src->properties()); | 186 Handle<FixedArray> src_props(src->properties()); |
185 Object* result = t.Call(*src); | 187 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
186 CHECK_EQ(*src_props, result); | 188 CHECK_EQ(*src_props, result); |
| 189 } |
187 } | 190 } |
188 | 191 |
189 | 192 |
190 TEST(RunLoadStoreMap) { | 193 TEST(RunLoadStoreMap) { |
191 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged, kMachineTagged); | 194 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged, kMachineTagged); |
192 FieldAccess access = ForJSObjectMap(); | 195 FieldAccess access = ForJSObjectMap(); |
193 Node* load = t.LoadField(access, t.Parameter(0)); | 196 Node* load = t.LoadField(access, t.Parameter(0)); |
194 t.StoreField(access, t.Parameter(1), load); | 197 t.StoreField(access, t.Parameter(1), load); |
195 t.Return(load); | 198 t.Return(load); |
196 | 199 |
197 t.LowerAllNodes(); | 200 t.LowerAllNodes(); |
198 | 201 |
199 if (!Pipeline::SupportedTarget()) return; | 202 if (Pipeline::SupportedTarget()) { |
200 | 203 t.GenerateCode(); |
201 Handle<JSObject> src = TestObject(); | 204 Handle<JSObject> src = TestObject(); |
202 Handle<Map> src_map(src->map()); | 205 Handle<Map> src_map(src->map()); |
203 Handle<JSObject> dst = TestObject(); | 206 Handle<JSObject> dst = TestObject(); |
204 CHECK(src->map() != dst->map()); | 207 CHECK(src->map() != dst->map()); |
205 Object* result = t.Call(*src, *dst); | 208 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call |
206 CHECK(result->IsMap()); | 209 CHECK(result->IsMap()); |
207 CHECK_EQ(*src_map, result); | 210 CHECK_EQ(*src_map, result); |
208 CHECK(*src_map == dst->map()); | 211 CHECK(*src_map == dst->map()); |
| 212 } |
209 } | 213 } |
210 | 214 |
211 | 215 |
212 TEST(RunLoadStoreFixedArrayIndex) { | 216 TEST(RunLoadStoreFixedArrayIndex) { |
213 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); | 217 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); |
214 ElementAccess access = ForFixedArrayElement(); | 218 ElementAccess access = ForFixedArrayElement(); |
215 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); | 219 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); |
216 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); | 220 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); |
217 t.Return(load); | 221 t.Return(load); |
218 | 222 |
219 t.LowerAllNodes(); | 223 t.LowerAllNodes(); |
220 | 224 |
221 if (!Pipeline::SupportedTarget()) return; | 225 if (Pipeline::SupportedTarget()) { |
222 | 226 t.GenerateCode(); |
223 Handle<FixedArray> array = t.factory()->NewFixedArray(2); | 227 Handle<FixedArray> array = t.factory()->NewFixedArray(2); |
224 Handle<JSObject> src = TestObject(); | 228 Handle<JSObject> src = TestObject(); |
225 Handle<JSObject> dst = TestObject(); | 229 Handle<JSObject> dst = TestObject(); |
226 array->set(0, *src); | 230 array->set(0, *src); |
227 array->set(1, *dst); | 231 array->set(1, *dst); |
228 Object* result = t.Call(*array); | 232 Object* result = t.Call(*array); |
229 CHECK_EQ(*src, result); | 233 CHECK_EQ(*src, result); |
230 CHECK_EQ(*src, array->get(0)); | 234 CHECK_EQ(*src, array->get(0)); |
231 CHECK_EQ(*src, array->get(1)); | 235 CHECK_EQ(*src, array->get(1)); |
| 236 } |
232 } | 237 } |
233 | 238 |
234 | 239 |
235 TEST(RunLoadStoreArrayBuffer) { | 240 TEST(RunLoadStoreArrayBuffer) { |
236 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged); | 241 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); |
237 const int index = 12; | 242 const int index = 12; |
238 FieldAccess access = ForArrayBufferBackingStore(); | |
239 Node* backing_store = t.LoadField(access, t.Parameter(0)); | |
240 ElementAccess buffer_access = ForBackingStoreElement(kMachineWord8); | 243 ElementAccess buffer_access = ForBackingStoreElement(kMachineWord8); |
| 244 Node* backing_store = |
| 245 t.LoadField(ForArrayBufferBackingStore(), t.Parameter(0)); |
241 Node* load = | 246 Node* load = |
242 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); | 247 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); |
243 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), | 248 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), |
244 load); | 249 load); |
245 t.Return(load); | 250 t.Return(t.jsgraph.TrueConstant()); |
246 | 251 |
247 t.LowerAllNodes(); | 252 t.LowerAllNodes(); |
248 | 253 |
249 if (!Pipeline::SupportedTarget()) return; | 254 if (Pipeline::SupportedTarget()) { |
| 255 t.GenerateCode(); |
| 256 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); |
| 257 const int array_length = 2 * index; |
| 258 Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length); |
| 259 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); |
| 260 for (int i = 0; i < array_length; i++) { |
| 261 data[i] = i; |
| 262 } |
250 | 263 |
251 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); | 264 // TODO(titzer): raw pointers in call |
252 const int array_length = 2 * index; | 265 Object* result = t.Call(*array); |
253 Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length); | 266 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
254 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); | 267 for (int i = 0; i < array_length; i++) { |
255 for (int i = 0; i < array_length; i++) { | 268 uint8_t expected = i; |
256 data[i] = i; | 269 if (i == (index + 1)) expected = index; |
257 } | 270 CHECK_EQ(data[i], expected); |
258 int32_t result = t.Call(*array); | 271 } |
259 CHECK_EQ(index, result); | |
260 for (int i = 0; i < array_length; i++) { | |
261 uint8_t expected = i; | |
262 if (i == (index + 1)) expected = result; | |
263 CHECK_EQ(data[i], expected); | |
264 } | 272 } |
265 } | 273 } |
266 | 274 |
267 | |
268 TEST(RunCopyFixedArray) { | |
269 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged, kMachineTagged); | |
270 | |
271 const int kArraySize = 15; | |
272 Node* one = t.Int32Constant(1); | |
273 Node* index = t.Int32Constant(0); | |
274 Node* limit = t.Int32Constant(kArraySize); | |
275 t.environment()->Push(index); | |
276 { | |
277 LoopBuilder loop(&t); | |
278 loop.BeginLoop(); | |
279 // Loop exit condition. | |
280 index = t.environment()->Top(); | |
281 Node* condition = t.Int32LessThan(index, limit); | |
282 loop.BreakUnless(condition); | |
283 // src[index] = dst[index]. | |
284 index = t.environment()->Pop(); | |
285 ElementAccess access = ForFixedArrayElement(); | |
286 Node* src = t.Parameter(0); | |
287 Node* load = t.LoadElement(access, src, index); | |
288 Node* dst = t.Parameter(1); | |
289 t.StoreElement(access, dst, index, load); | |
290 // index++ | |
291 index = t.Int32Add(index, one); | |
292 t.environment()->Push(index); | |
293 // continue. | |
294 loop.EndBody(); | |
295 loop.EndLoop(); | |
296 } | |
297 index = t.environment()->Pop(); | |
298 t.Return(index); | |
299 | |
300 t.LowerAllNodes(); | |
301 | |
302 if (!Pipeline::SupportedTarget()) return; | |
303 | |
304 Handle<FixedArray> src = t.factory()->NewFixedArray(kArraySize); | |
305 Handle<FixedArray> src_copy = t.factory()->NewFixedArray(kArraySize); | |
306 Handle<FixedArray> dst = t.factory()->NewFixedArray(kArraySize); | |
307 for (int i = 0; i < kArraySize; i++) { | |
308 src->set(i, *TestObject()); | |
309 src_copy->set(i, src->get(i)); | |
310 dst->set(i, *TestObject()); | |
311 CHECK_NE(src_copy->get(i), dst->get(i)); | |
312 } | |
313 CHECK_EQ(kArraySize, t.Call(*src, *dst)); | |
314 for (int i = 0; i < kArraySize; i++) { | |
315 CHECK_EQ(src_copy->get(i), dst->get(i)); | |
316 } | |
317 } | |
318 | |
319 | 275 |
320 TEST(RunLoadFieldFromUntaggedBase) { | 276 TEST(RunLoadFieldFromUntaggedBase) { |
321 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; | 277 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; |
322 | 278 |
323 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { | 279 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { |
324 int offset = static_cast<int>(i * sizeof(Smi*)); | 280 int offset = static_cast<int>(i * sizeof(Smi*)); |
325 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), | 281 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), |
326 Type::Integral32(), kMachineTagged}; | 282 Type::Integral32(), kMachineTagged}; |
327 | 283 |
328 SimplifiedGraphBuilderTester<Object*> t; | 284 SimplifiedGraphBuilderTester<Object*> t; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 Smi* expected = Smi::FromInt(k); | 374 Smi* expected = Smi::FromInt(k); |
419 smis[i + j] = Smi::FromInt(-100); | 375 smis[i + j] = Smi::FromInt(-100); |
420 CHECK_EQ(expected, t.Call(expected)); | 376 CHECK_EQ(expected, t.Call(expected)); |
421 CHECK_EQ(expected, smis[i + j]); | 377 CHECK_EQ(expected, smis[i + j]); |
422 } | 378 } |
423 | 379 |
424 // TODO(titzer): assert the contents of the array. | 380 // TODO(titzer): assert the contents of the array. |
425 } | 381 } |
426 } | 382 } |
427 } | 383 } |
| 384 |
| 385 |
| 386 // A helper class for accessing fields and elements of various types, on both |
| 387 // tagged and untagged base pointers. Contains both tagged and untagged buffers |
| 388 // for testing direct memory access from generated code. |
| 389 template <typename E> |
| 390 class AccessTester : public HandleAndZoneScope { |
| 391 public: |
| 392 bool tagged; |
| 393 MachineRepresentation rep; |
| 394 E* original_elements; |
| 395 int num_elements; |
| 396 E* untagged_array; |
| 397 Handle<ByteArray> tagged_array; // TODO(titzer): use FixedArray for tagged. |
| 398 |
| 399 AccessTester(bool t, MachineRepresentation r, E* orig, int num) |
| 400 : tagged(t), |
| 401 rep(r), |
| 402 original_elements(orig), |
| 403 num_elements(num), |
| 404 untagged_array(static_cast<E*>(malloc(ByteSize()))), |
| 405 tagged_array(main_isolate()->factory()->NewByteArray(ByteSize())) { |
| 406 Reinitialize(); |
| 407 } |
| 408 |
| 409 ~AccessTester() { free(untagged_array); } |
| 410 |
| 411 size_t ByteSize() { return num_elements * sizeof(E); } |
| 412 |
| 413 // Nuke both {untagged_array} and {tagged_array} with {original_elements}. |
| 414 void Reinitialize() { |
| 415 memcpy(untagged_array, original_elements, ByteSize()); |
| 416 CHECK_EQ(ByteSize(), tagged_array->length()); |
| 417 E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress()); |
| 418 memcpy(raw, original_elements, ByteSize()); |
| 419 } |
| 420 |
| 421 // Create and run code that copies the element in either {untagged_array} |
| 422 // or {tagged_array} at index {from_index} to index {to_index}. |
| 423 void RunCopyElement(int from_index, int to_index) { |
| 424 // TODO(titzer): test element and field accesses where the base is not |
| 425 // a constant in the code. |
| 426 BoundsCheck(from_index); |
| 427 BoundsCheck(to_index); |
| 428 ElementAccess access = GetElementAccess(); |
| 429 |
| 430 SimplifiedGraphBuilderTester<Object*> t; |
| 431 Node* ptr = GetBaseNode(&t); |
| 432 Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index)); |
| 433 t.StoreElement(access, ptr, t.Int32Constant(to_index), load); |
| 434 t.Return(t.jsgraph.TrueConstant()); |
| 435 t.LowerAllNodes(); |
| 436 t.GenerateCode(); |
| 437 |
| 438 if (Pipeline::SupportedTarget()) { |
| 439 Object* result = t.Call(); |
| 440 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
| 441 } |
| 442 } |
| 443 |
| 444 // Create and run code that copies the field in either {untagged_array} |
| 445 // or {tagged_array} at index {from_index} to index {to_index}. |
| 446 void RunCopyField(int from_index, int to_index) { |
| 447 BoundsCheck(from_index); |
| 448 BoundsCheck(to_index); |
| 449 FieldAccess from_access = GetFieldAccess(from_index); |
| 450 FieldAccess to_access = GetFieldAccess(to_index); |
| 451 |
| 452 SimplifiedGraphBuilderTester<Object*> t; |
| 453 Node* ptr = GetBaseNode(&t); |
| 454 Node* load = t.LoadField(from_access, ptr); |
| 455 t.StoreField(to_access, ptr, load); |
| 456 t.Return(t.jsgraph.TrueConstant()); |
| 457 t.LowerAllNodes(); |
| 458 t.GenerateCode(); |
| 459 |
| 460 if (Pipeline::SupportedTarget()) { |
| 461 Object* result = t.Call(); |
| 462 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
| 463 } |
| 464 } |
| 465 |
| 466 // Create and run code that copies the elements from {this} to {that}. |
| 467 void RunCopyElements(AccessTester<E>* that) { |
| 468 SimplifiedGraphBuilderTester<Object*> t; |
| 469 |
| 470 Node* one = t.Int32Constant(1); |
| 471 Node* index = t.Int32Constant(0); |
| 472 Node* limit = t.Int32Constant(num_elements); |
| 473 t.environment()->Push(index); |
| 474 Node* src = this->GetBaseNode(&t); |
| 475 Node* dst = that->GetBaseNode(&t); |
| 476 { |
| 477 LoopBuilder loop(&t); |
| 478 loop.BeginLoop(); |
| 479 // Loop exit condition |
| 480 index = t.environment()->Top(); |
| 481 Node* condition = t.Int32LessThan(index, limit); |
| 482 loop.BreakUnless(condition); |
| 483 // dst[index] = src[index] |
| 484 index = t.environment()->Pop(); |
| 485 Node* load = t.LoadElement(this->GetElementAccess(), src, index); |
| 486 t.StoreElement(that->GetElementAccess(), dst, index, load); |
| 487 // index++ |
| 488 index = t.Int32Add(index, one); |
| 489 t.environment()->Push(index); |
| 490 // continue |
| 491 loop.EndBody(); |
| 492 loop.EndLoop(); |
| 493 } |
| 494 index = t.environment()->Pop(); |
| 495 t.Return(t.jsgraph.TrueConstant()); |
| 496 t.LowerAllNodes(); |
| 497 t.GenerateCode(); |
| 498 |
| 499 if (Pipeline::SupportedTarget()) { |
| 500 Object* result = t.Call(); |
| 501 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
| 502 } |
| 503 } |
| 504 |
| 505 E GetElement(int index) { |
| 506 BoundsCheck(index); |
| 507 if (tagged) { |
| 508 E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress()); |
| 509 return raw[index]; |
| 510 } else { |
| 511 return untagged_array[index]; |
| 512 } |
| 513 } |
| 514 |
| 515 private: |
| 516 ElementAccess GetElementAccess() { |
| 517 ElementAccess access = {tagged ? kTaggedBase : kUntaggedBase, |
| 518 tagged ? FixedArrayBase::kHeaderSize : 0, |
| 519 Type::Any(), rep}; |
| 520 return access; |
| 521 } |
| 522 |
| 523 FieldAccess GetFieldAccess(int field) { |
| 524 int offset = field * sizeof(E); |
| 525 FieldAccess access = {tagged ? kTaggedBase : kUntaggedBase, |
| 526 offset + (tagged ? FixedArrayBase::kHeaderSize : 0), |
| 527 Handle<Name>(), Type::Any(), rep}; |
| 528 return access; |
| 529 } |
| 530 |
| 531 template <typename T> |
| 532 Node* GetBaseNode(SimplifiedGraphBuilderTester<T>* t) { |
| 533 return tagged ? t->HeapConstant(tagged_array) |
| 534 : t->PointerConstant(untagged_array); |
| 535 } |
| 536 |
| 537 void BoundsCheck(int index) { |
| 538 CHECK_GE(index, 0); |
| 539 CHECK_LT(index, num_elements); |
| 540 CHECK_EQ(ByteSize(), tagged_array->length()); |
| 541 } |
| 542 }; |
| 543 |
| 544 |
| 545 template <typename E> |
| 546 static void RunAccessTest(MachineRepresentation rep, E* original_elements, |
| 547 size_t num) { |
| 548 int num_elements = static_cast<int>(num); |
| 549 |
| 550 for (int taggedness = 0; taggedness < 2; taggedness++) { |
| 551 AccessTester<E> a(taggedness == 1, rep, original_elements, num_elements); |
| 552 for (int field = 0; field < 2; field++) { |
| 553 for (int i = 0; i < num_elements - 1; i++) { |
| 554 a.Reinitialize(); |
| 555 if (field == 0) { |
| 556 a.RunCopyField(i, i + 1); // Test field read/write. |
| 557 } else { |
| 558 a.RunCopyElement(i, i + 1); // Test element read/write. |
| 559 } |
| 560 if (Pipeline::SupportedTarget()) { // verify. |
| 561 for (int j = 0; j < num_elements; j++) { |
| 562 E expect = |
| 563 j == (i + 1) ? original_elements[i] : original_elements[j]; |
| 564 CHECK_EQ(expect, a.GetElement(j)); |
| 565 } |
| 566 } |
| 567 } |
| 568 } |
| 569 } |
| 570 // Test array copy. |
| 571 for (int tf = 0; tf < 2; tf++) { |
| 572 for (int tt = 0; tt < 2; tt++) { |
| 573 AccessTester<E> a(tf == 1, rep, original_elements, num_elements); |
| 574 AccessTester<E> b(tt == 1, rep, original_elements, num_elements); |
| 575 a.RunCopyElements(&b); |
| 576 if (Pipeline::SupportedTarget()) { // verify. |
| 577 for (int i = 0; i < num_elements; i++) { |
| 578 CHECK_EQ(a.GetElement(i), b.GetElement(i)); |
| 579 } |
| 580 } |
| 581 } |
| 582 } |
| 583 } |
| 584 |
| 585 |
| 586 TEST(RunAccessTests_uint8) { |
| 587 uint8_t data[] = {0x07, 0x16, 0x25, 0x34, 0x43, 0x99, |
| 588 0xab, 0x78, 0x89, 0x19, 0x2b, 0x38}; |
| 589 RunAccessTest<uint8_t>(kMachineWord8, data, ARRAY_SIZE(data)); |
| 590 } |
| 591 |
| 592 |
| 593 TEST(RunAccessTests_uint16) { |
| 594 uint16_t data[] = {0x071a, 0x162b, 0x253c, 0x344d, 0x435e, 0x7777}; |
| 595 RunAccessTest<uint16_t>(kMachineWord16, data, ARRAY_SIZE(data)); |
| 596 } |
| 597 |
| 598 |
| 599 TEST(RunAccessTests_int32) { |
| 600 int32_t data[] = {0xf10733aa, 0xf21644bb, 0xf32555cc, |
| 601 0xf43466dd, 0xf54377ee, 0x34455667}; |
| 602 RunAccessTest<int32_t>(kMachineWord32, data, ARRAY_SIZE(data)); |
| 603 } |
| 604 |
| 605 |
| 606 TEST(RunAccessTests_int64) { |
| 607 if (kPointerSize != 8) return; |
| 608 int64_t data[] = {0x1011121314151617L, 0x2021222324252627L, |
| 609 0x3031323334353637L, 0xa0a1a2a3a4a5a6a7L, |
| 610 0xf0f1f2f3f4f5f6f7L}; |
| 611 RunAccessTest<int64_t>(kMachineWord64, data, ARRAY_SIZE(data)); |
| 612 } |
| 613 |
| 614 |
| 615 TEST(RunAccessTests_float64) { |
| 616 double data[] = {1.25, -1.25, 2.75, 11.0, 11100.8}; |
| 617 RunAccessTest<double>(kMachineFloat64, data, ARRAY_SIZE(data)); |
| 618 } |
| 619 |
| 620 |
| 621 TEST(RunAccessTests_Smi) { |
| 622 Smi* data[] = {Smi::FromInt(-1), Smi::FromInt(-9), |
| 623 Smi::FromInt(0), Smi::FromInt(666), |
| 624 Smi::FromInt(77777), Smi::FromInt(Smi::kMaxValue)}; |
| 625 RunAccessTest<Smi*>(kMachineTagged, data, ARRAY_SIZE(data)); |
| 626 } |
OLD | NEW |