Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: test/unittests/compiler/js-typed-lowering-unittest.cc

Issue 763963002: [turbofan] Add checked load/store operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Reapply fix. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "src/compiler/access-builder.h" 5 #include "src/compiler/access-builder.h"
6 #include "src/compiler/js-graph.h" 6 #include "src/compiler/js-graph.h"
7 #include "src/compiler/js-operator.h" 7 #include "src/compiler/js-operator.h"
8 #include "src/compiler/js-typed-lowering.h" 8 #include "src/compiler/js-typed-lowering.h"
9 #include "src/compiler/machine-operator.h" 9 #include "src/compiler/machine-operator.h"
10 #include "src/compiler/node-properties-inl.h" 10 #include "src/compiler/node-properties-inl.h"
11 #include "src/compiler/typer.h" 11 #include "src/compiler/typer.h"
12 #include "test/unittests/compiler/compiler-test-utils.h" 12 #include "test/unittests/compiler/compiler-test-utils.h"
13 #include "test/unittests/compiler/graph-unittest.h" 13 #include "test/unittests/compiler/graph-unittest.h"
14 #include "test/unittests/compiler/node-test-utils.h" 14 #include "test/unittests/compiler/node-test-utils.h"
15 15
16 namespace v8 { 16 namespace v8 {
17 namespace internal { 17 namespace internal {
18 namespace compiler { 18 namespace compiler {
19 19
20 namespace { 20 namespace {
21 21
22 const ExternalArrayType kExternalArrayTypes[] = { 22 const ExternalArrayType kExternalArrayTypes[] = {
23 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) kExternal##Type##Array, 23 kExternalUint8Array, kExternalInt8Array, kExternalUint16Array,
24 TYPED_ARRAYS(TYPED_ARRAY_CASE) 24 kExternalInt16Array, kExternalUint32Array, kExternalInt32Array,
25 #undef TYPED_ARRAY_CASE 25 kExternalFloat32Array, kExternalFloat64Array};
26 };
27 26
28 27
29 Type* const kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(), 28 Type* const kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
30 Type::Number(), Type::String(), Type::Object()}; 29 Type::Number(), Type::String(), Type::Object()};
31 30
32 31
33 const StrictMode kStrictModes[] = {SLOPPY, STRICT}; 32 const StrictMode kStrictModes[] = {SLOPPY, STRICT};
34 33
35 } // namespace 34 } // namespace
36 35
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) { 236 TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
238 const size_t kLength = 17; 237 const size_t kLength = 17;
239 double backing_store[kLength]; 238 double backing_store[kLength];
240 Handle<JSArrayBuffer> buffer = 239 Handle<JSArrayBuffer> buffer =
241 NewArrayBuffer(backing_store, sizeof(backing_store)); 240 NewArrayBuffer(backing_store, sizeof(backing_store));
242 VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(), 241 VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
243 FeedbackVectorICSlot::Invalid()); 242 FeedbackVectorICSlot::Invalid());
244 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { 243 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
245 Handle<JSTypedArray> array = 244 Handle<JSTypedArray> array =
246 factory()->NewJSTypedArray(type, buffer, 0, kLength); 245 factory()->NewJSTypedArray(type, buffer, 0, kLength);
246 int const element_size = static_cast<int>(array->element_size());
247 247
248 Node* key = Parameter(Type::Integral32()); 248 Node* key = Parameter(
249 Type::Range(factory()->NewNumber(kMinInt / element_size),
250 factory()->NewNumber(kMaxInt / element_size), zone()));
249 Node* base = HeapConstant(array); 251 Node* base = HeapConstant(array);
250 Node* context = UndefinedConstant(); 252 Node* context = UndefinedConstant();
251 Node* effect = graph()->start(); 253 Node* effect = graph()->start();
254 Node* control = graph()->start();
255 Node* node = graph()->NewNode(javascript()->LoadProperty(feedback), base,
256 key, context);
257 if (FLAG_turbo_deoptimization) {
258 node->AppendInput(zone(), UndefinedConstant());
259 }
260 node->AppendInput(zone(), effect);
261 node->AppendInput(zone(), control);
262 Reduction r = Reduce(node);
263
264 Matcher<Node*> offset_matcher =
265 element_size == 1
266 ? key
267 : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
268
269 ASSERT_TRUE(r.Changed());
270 EXPECT_THAT(
271 r.replacement(),
272 IsLoadBuffer(BufferAccess(type),
273 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
274 offset_matcher,
275 IsNumberConstant(array->byte_length()->Number()), effect,
276 control));
277 }
278 }
279
280
281 TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
282 const size_t kLength = 17;
283 double backing_store[kLength];
284 Handle<JSArrayBuffer> buffer =
285 NewArrayBuffer(backing_store, sizeof(backing_store));
286 VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
287 FeedbackVectorICSlot::Invalid());
288 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
289 Handle<JSTypedArray> array =
290 factory()->NewJSTypedArray(type, buffer, 0, kLength);
291 ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
292
293 int min = random_number_generator()->NextInt(static_cast<int>(kLength));
294 int max = random_number_generator()->NextInt(static_cast<int>(kLength));
295 if (min > max) std::swap(min, max);
296 Node* key = Parameter(Type::Range(factory()->NewNumber(min),
297 factory()->NewNumber(max), zone()));
298 Node* base = HeapConstant(array);
299 Node* context = UndefinedConstant();
300 Node* effect = graph()->start();
252 Node* control = graph()->start(); 301 Node* control = graph()->start();
253 Node* node = graph()->NewNode(javascript()->LoadProperty(feedback), base, 302 Node* node = graph()->NewNode(javascript()->LoadProperty(feedback), base,
254 key, context); 303 key, context);
255 if (FLAG_turbo_deoptimization) { 304 if (FLAG_turbo_deoptimization) {
256 node->AppendInput(zone(), UndefinedConstant()); 305 node->AppendInput(zone(), UndefinedConstant());
257 } 306 }
258 node->AppendInput(zone(), effect); 307 node->AppendInput(zone(), effect);
259 node->AppendInput(zone(), control); 308 node->AppendInput(zone(), control);
260 Reduction r = Reduce(node); 309 Reduction r = Reduce(node);
261 310
262 ASSERT_TRUE(r.Changed()); 311 ASSERT_TRUE(r.Changed());
263 EXPECT_THAT(r.replacement(), 312 EXPECT_THAT(
264 IsLoadElement( 313 r.replacement(),
265 AccessBuilder::ForTypedArrayElement(type, true), 314 IsLoadElement(access,
266 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])), 315 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
267 key, IsNumberConstant(array->length()->Number()), effect)); 316 key, effect, control));
268 } 317 }
269 } 318 }
270 319
271 320
272 // ----------------------------------------------------------------------------- 321 // -----------------------------------------------------------------------------
273 // JSStoreProperty 322 // JSStoreProperty
274 323
275 324
276 TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) { 325 TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
277 const size_t kLength = 17; 326 const size_t kLength = 17;
278 double backing_store[kLength]; 327 double backing_store[kLength];
279 Handle<JSArrayBuffer> buffer = 328 Handle<JSArrayBuffer> buffer =
280 NewArrayBuffer(backing_store, sizeof(backing_store)); 329 NewArrayBuffer(backing_store, sizeof(backing_store));
281 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { 330 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
282 TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) { 331 TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
283 Handle<JSTypedArray> array = 332 Handle<JSTypedArray> array =
284 factory()->NewJSTypedArray(type, buffer, 0, kLength); 333 factory()->NewJSTypedArray(type, buffer, 0, kLength);
334 int const element_size = static_cast<int>(array->element_size());
285 335
286 Node* key = Parameter(Type::Integral32()); 336 Node* key = Parameter(
337 Type::Range(factory()->NewNumber(kMinInt / element_size),
338 factory()->NewNumber(kMaxInt / element_size), zone()));
287 Node* base = HeapConstant(array); 339 Node* base = HeapConstant(array);
288 Node* value = 340 Node* value =
289 Parameter(AccessBuilder::ForTypedArrayElement(type, true).type); 341 Parameter(AccessBuilder::ForTypedArrayElement(type, true).type);
290 Node* context = UndefinedConstant(); 342 Node* context = UndefinedConstant();
291 Node* effect = graph()->start(); 343 Node* effect = graph()->start();
292 Node* control = graph()->start(); 344 Node* control = graph()->start();
293 Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode), 345 Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode),
294 base, key, value, context); 346 base, key, value, context);
295 if (FLAG_turbo_deoptimization) { 347 if (FLAG_turbo_deoptimization) {
296 node->AppendInput(zone(), UndefinedConstant()); 348 node->AppendInput(zone(), UndefinedConstant());
297 } 349 }
298 node->AppendInput(zone(), effect); 350 node->AppendInput(zone(), effect);
299 node->AppendInput(zone(), control); 351 node->AppendInput(zone(), control);
300 Reduction r = Reduce(node); 352 Reduction r = Reduce(node);
301 353
354 Matcher<Node*> offset_matcher =
355 element_size == 1
356 ? key
357 : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
358
302 ASSERT_TRUE(r.Changed()); 359 ASSERT_TRUE(r.Changed());
303 EXPECT_THAT(r.replacement(), 360 EXPECT_THAT(
304 IsStoreElement( 361 r.replacement(),
305 AccessBuilder::ForTypedArrayElement(type, true), 362 IsStoreBuffer(BufferAccess(type),
306 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])), 363 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
307 key, IsNumberConstant(array->length()->Number()), value, 364 offset_matcher,
308 effect, control)); 365 IsNumberConstant(array->byte_length()->Number()), value,
366 effect, control));
309 } 367 }
310 } 368 }
311 } 369 }
312 370
313 371
314 TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) { 372 TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
315 const size_t kLength = 17; 373 const size_t kLength = 17;
316 double backing_store[kLength]; 374 double backing_store[kLength];
317 Handle<JSArrayBuffer> buffer = 375 Handle<JSArrayBuffer> buffer =
318 NewArrayBuffer(backing_store, sizeof(backing_store)); 376 NewArrayBuffer(backing_store, sizeof(backing_store));
319 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { 377 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
320 TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) { 378 TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
321 Handle<JSTypedArray> array = 379 Handle<JSTypedArray> array =
322 factory()->NewJSTypedArray(type, buffer, 0, kLength); 380 factory()->NewJSTypedArray(type, buffer, 0, kLength);
381 int const element_size = static_cast<int>(array->element_size());
323 382
324 Node* key = Parameter(Type::Integral32()); 383 Node* key = Parameter(
384 Type::Range(factory()->NewNumber(kMinInt / element_size),
385 factory()->NewNumber(kMaxInt / element_size), zone()));
325 Node* base = HeapConstant(array); 386 Node* base = HeapConstant(array);
326 Node* value = Parameter(Type::Any()); 387 Node* value = Parameter(Type::Any());
327 Node* context = UndefinedConstant(); 388 Node* context = UndefinedConstant();
328 Node* effect = graph()->start(); 389 Node* effect = graph()->start();
329 Node* control = graph()->start(); 390 Node* control = graph()->start();
330 Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode), 391 Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode),
331 base, key, value, context); 392 base, key, value, context);
332 if (FLAG_turbo_deoptimization) { 393 if (FLAG_turbo_deoptimization) {
333 node->AppendInput(zone(), UndefinedConstant()); 394 node->AppendInput(zone(), UndefinedConstant());
334 } 395 }
335 node->AppendInput(zone(), effect); 396 node->AppendInput(zone(), effect);
336 node->AppendInput(zone(), control); 397 node->AppendInput(zone(), control);
337 Reduction r = Reduce(node); 398 Reduction r = Reduce(node);
338 399
400 Matcher<Node*> offset_matcher =
401 element_size == 1
402 ? key
403 : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
404
339 Matcher<Node*> value_matcher = 405 Matcher<Node*> value_matcher =
340 IsToNumber(value, context, effect, control); 406 IsToNumber(value, context, effect, control);
341 Matcher<Node*> effect_matcher = value_matcher; 407 Matcher<Node*> effect_matcher = value_matcher;
342 if (AccessBuilder::ForTypedArrayElement(type, true) 408 if (AccessBuilder::ForTypedArrayElement(type, true)
343 .type->Is(Type::Signed32())) { 409 .type->Is(Type::Signed32())) {
344 value_matcher = IsNumberToInt32(value_matcher); 410 value_matcher = IsNumberToInt32(value_matcher);
345 } else if (AccessBuilder::ForTypedArrayElement(type, true) 411 } else if (AccessBuilder::ForTypedArrayElement(type, true)
346 .type->Is(Type::Unsigned32())) { 412 .type->Is(Type::Unsigned32())) {
347 value_matcher = IsNumberToUint32(value_matcher); 413 value_matcher = IsNumberToUint32(value_matcher);
348 } 414 }
349 415
350 ASSERT_TRUE(r.Changed()); 416 ASSERT_TRUE(r.Changed());
351 EXPECT_THAT(r.replacement(), 417 EXPECT_THAT(
352 IsStoreElement( 418 r.replacement(),
353 AccessBuilder::ForTypedArrayElement(type, true), 419 IsStoreBuffer(BufferAccess(type),
354 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])), 420 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
355 key, IsNumberConstant(array->length()->Number()), 421 offset_matcher,
356 value_matcher, effect_matcher, control)); 422 IsNumberConstant(array->byte_length()->Number()),
423 value_matcher, effect_matcher, control));
357 } 424 }
358 } 425 }
359 } 426 }
427
428
429 TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
430 const size_t kLength = 17;
431 double backing_store[kLength];
432 Handle<JSArrayBuffer> buffer =
433 NewArrayBuffer(backing_store, sizeof(backing_store));
434 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
435 TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
436 Handle<JSTypedArray> array =
437 factory()->NewJSTypedArray(type, buffer, 0, kLength);
438 ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
439
440 int min = random_number_generator()->NextInt(static_cast<int>(kLength));
441 int max = random_number_generator()->NextInt(static_cast<int>(kLength));
442 if (min > max) std::swap(min, max);
443 Node* key = Parameter(Type::Range(factory()->NewNumber(min),
444 factory()->NewNumber(max), zone()));
445 Node* base = HeapConstant(array);
446 Node* value = Parameter(access.type);
447 Node* context = UndefinedConstant();
448 Node* effect = graph()->start();
449 Node* control = graph()->start();
450 Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode),
451 base, key, value, context);
452 if (FLAG_turbo_deoptimization) {
453 node->AppendInput(zone(), UndefinedConstant());
454 }
455 node->AppendInput(zone(), effect);
456 node->AppendInput(zone(), control);
457 Reduction r = Reduce(node);
458
459 ASSERT_TRUE(r.Changed());
460 EXPECT_THAT(
461 r.replacement(),
462 IsStoreElement(
463 access, IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
464 key, value, effect, control));
465 }
466 }
467 }
360 468
361 } // namespace compiler 469 } // namespace compiler
362 } // namespace internal 470 } // namespace internal
363 } // namespace v8 471 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/compiler/test-simplified-lowering.cc ('k') | test/unittests/compiler/machine-operator-reducer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698