| Index: test/unittests/compiler/js-typed-lowering-unittest.cc
|
| diff --git a/test/unittests/compiler/js-typed-lowering-unittest.cc b/test/unittests/compiler/js-typed-lowering-unittest.cc
|
| index 4d56393c359ad4571e36afc36fa308ef83d43ac2..287bba218a952dcc2eda4e8a8c14a0654a9fe5e4 100644
|
| --- a/test/unittests/compiler/js-typed-lowering-unittest.cc
|
| +++ b/test/unittests/compiler/js-typed-lowering-unittest.cc
|
| @@ -20,10 +20,9 @@ namespace compiler {
|
| namespace {
|
|
|
| const ExternalArrayType kExternalArrayTypes[] = {
|
| -#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) kExternal##Type##Array,
|
| - TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
| -#undef TYPED_ARRAY_CASE
|
| -};
|
| + kExternalUint8Array, kExternalInt8Array, kExternalUint16Array,
|
| + kExternalInt16Array, kExternalUint32Array, kExternalInt32Array,
|
| + kExternalFloat32Array, kExternalFloat64Array};
|
|
|
|
|
| Type* const kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
|
| @@ -244,8 +243,58 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
|
| TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
|
| Handle<JSTypedArray> array =
|
| factory()->NewJSTypedArray(type, buffer, 0, kLength);
|
| + int const element_size = static_cast<int>(array->element_size());
|
| +
|
| + Node* key = Parameter(
|
| + Type::Range(factory()->NewNumber(kMinInt / element_size),
|
| + factory()->NewNumber(kMaxInt / element_size), zone()));
|
| + Node* base = HeapConstant(array);
|
| + Node* context = UndefinedConstant();
|
| + Node* effect = graph()->start();
|
| + Node* control = graph()->start();
|
| + Node* node = graph()->NewNode(javascript()->LoadProperty(feedback), base,
|
| + key, context);
|
| + if (FLAG_turbo_deoptimization) {
|
| + node->AppendInput(zone(), UndefinedConstant());
|
| + }
|
| + node->AppendInput(zone(), effect);
|
| + node->AppendInput(zone(), control);
|
| + Reduction r = Reduce(node);
|
| +
|
| + Matcher<Node*> offset_matcher =
|
| + element_size == 1
|
| + ? key
|
| + : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
|
| +
|
| + ASSERT_TRUE(r.Changed());
|
| + EXPECT_THAT(
|
| + r.replacement(),
|
| + IsLoadBuffer(BufferAccess(type),
|
| + IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
|
| + offset_matcher,
|
| + IsNumberConstant(array->byte_length()->Number()), effect,
|
| + control));
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
|
| + const size_t kLength = 17;
|
| + double backing_store[kLength];
|
| + Handle<JSArrayBuffer> buffer =
|
| + NewArrayBuffer(backing_store, sizeof(backing_store));
|
| + VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
|
| + FeedbackVectorICSlot::Invalid());
|
| + TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
|
| + Handle<JSTypedArray> array =
|
| + factory()->NewJSTypedArray(type, buffer, 0, kLength);
|
| + ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
|
|
|
| - Node* key = Parameter(Type::Integral32());
|
| + int min = random_number_generator()->NextInt(static_cast<int>(kLength));
|
| + int max = random_number_generator()->NextInt(static_cast<int>(kLength));
|
| + if (min > max) std::swap(min, max);
|
| + Node* key = Parameter(Type::Range(factory()->NewNumber(min),
|
| + factory()->NewNumber(max), zone()));
|
| Node* base = HeapConstant(array);
|
| Node* context = UndefinedConstant();
|
| Node* effect = graph()->start();
|
| @@ -260,11 +309,11 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
|
| Reduction r = Reduce(node);
|
|
|
| ASSERT_TRUE(r.Changed());
|
| - EXPECT_THAT(r.replacement(),
|
| - IsLoadElement(
|
| - AccessBuilder::ForTypedArrayElement(type, true),
|
| - IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
|
| - key, IsNumberConstant(array->length()->Number()), effect));
|
| + EXPECT_THAT(
|
| + r.replacement(),
|
| + IsLoadElement(access,
|
| + IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
|
| + key, effect, control));
|
| }
|
| }
|
|
|
| @@ -282,8 +331,11 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
|
| TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
|
| Handle<JSTypedArray> array =
|
| factory()->NewJSTypedArray(type, buffer, 0, kLength);
|
| + int const element_size = static_cast<int>(array->element_size());
|
|
|
| - Node* key = Parameter(Type::Integral32());
|
| + Node* key = Parameter(
|
| + Type::Range(factory()->NewNumber(kMinInt / element_size),
|
| + factory()->NewNumber(kMaxInt / element_size), zone()));
|
| Node* base = HeapConstant(array);
|
| Node* value =
|
| Parameter(AccessBuilder::ForTypedArrayElement(type, true).type);
|
| @@ -299,13 +351,19 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
|
| node->AppendInput(zone(), control);
|
| Reduction r = Reduce(node);
|
|
|
| + Matcher<Node*> offset_matcher =
|
| + element_size == 1
|
| + ? key
|
| + : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
|
| +
|
| ASSERT_TRUE(r.Changed());
|
| - EXPECT_THAT(r.replacement(),
|
| - IsStoreElement(
|
| - AccessBuilder::ForTypedArrayElement(type, true),
|
| - IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
|
| - key, IsNumberConstant(array->length()->Number()), value,
|
| - effect, control));
|
| + EXPECT_THAT(
|
| + r.replacement(),
|
| + IsStoreBuffer(BufferAccess(type),
|
| + IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
|
| + offset_matcher,
|
| + IsNumberConstant(array->byte_length()->Number()), value,
|
| + effect, control));
|
| }
|
| }
|
| }
|
| @@ -320,8 +378,11 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
|
| TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
|
| Handle<JSTypedArray> array =
|
| factory()->NewJSTypedArray(type, buffer, 0, kLength);
|
| + int const element_size = static_cast<int>(array->element_size());
|
|
|
| - Node* key = Parameter(Type::Integral32());
|
| + Node* key = Parameter(
|
| + Type::Range(factory()->NewNumber(kMinInt / element_size),
|
| + factory()->NewNumber(kMaxInt / element_size), zone()));
|
| Node* base = HeapConstant(array);
|
| Node* value = Parameter(Type::Any());
|
| Node* context = UndefinedConstant();
|
| @@ -336,6 +397,11 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
|
| node->AppendInput(zone(), control);
|
| Reduction r = Reduce(node);
|
|
|
| + Matcher<Node*> offset_matcher =
|
| + element_size == 1
|
| + ? key
|
| + : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
|
| +
|
| Matcher<Node*> value_matcher =
|
| IsToNumber(value, context, effect, control);
|
| Matcher<Node*> effect_matcher = value_matcher;
|
| @@ -348,12 +414,54 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
|
| }
|
|
|
| ASSERT_TRUE(r.Changed());
|
| - EXPECT_THAT(r.replacement(),
|
| - IsStoreElement(
|
| - AccessBuilder::ForTypedArrayElement(type, true),
|
| - IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
|
| - key, IsNumberConstant(array->length()->Number()),
|
| - value_matcher, effect_matcher, control));
|
| + EXPECT_THAT(
|
| + r.replacement(),
|
| + IsStoreBuffer(BufferAccess(type),
|
| + IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
|
| + offset_matcher,
|
| + IsNumberConstant(array->byte_length()->Number()),
|
| + value_matcher, effect_matcher, control));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
|
| + const size_t kLength = 17;
|
| + double backing_store[kLength];
|
| + Handle<JSArrayBuffer> buffer =
|
| + NewArrayBuffer(backing_store, sizeof(backing_store));
|
| + TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
|
| + TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
|
| + Handle<JSTypedArray> array =
|
| + factory()->NewJSTypedArray(type, buffer, 0, kLength);
|
| + ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
|
| +
|
| + int min = random_number_generator()->NextInt(static_cast<int>(kLength));
|
| + int max = random_number_generator()->NextInt(static_cast<int>(kLength));
|
| + if (min > max) std::swap(min, max);
|
| + Node* key = Parameter(Type::Range(factory()->NewNumber(min),
|
| + factory()->NewNumber(max), zone()));
|
| + Node* base = HeapConstant(array);
|
| + Node* value = Parameter(access.type);
|
| + Node* context = UndefinedConstant();
|
| + Node* effect = graph()->start();
|
| + Node* control = graph()->start();
|
| + Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode),
|
| + base, key, value, context);
|
| + if (FLAG_turbo_deoptimization) {
|
| + node->AppendInput(zone(), UndefinedConstant());
|
| + }
|
| + node->AppendInput(zone(), effect);
|
| + node->AppendInput(zone(), control);
|
| + Reduction r = Reduce(node);
|
| +
|
| + ASSERT_TRUE(r.Changed());
|
| + EXPECT_THAT(
|
| + r.replacement(),
|
| + IsStoreElement(
|
| + access, IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
|
| + key, value, effect, control));
|
| }
|
| }
|
| }
|
|
|