Commit 7e84fb26 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Don't embed backing store of neutered array buffer.

R=jochen@chromium.org

Review URL: https://codereview.chromium.org/1127193003

Cr-Commit-Position: refs/heads/master@{#28308}
parent 93662ec2
......@@ -829,39 +829,40 @@ Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) {
Node* key = NodeProperties::GetValueInput(node, 1);
Node* base = NodeProperties::GetValueInput(node, 0);
Type* key_type = NodeProperties::GetBounds(key).upper;
// TODO(mstarzinger): This lowering is not correct if:
// a) The typed array or it's buffer is neutered.
HeapObjectMatcher<Object> mbase(base);
if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) {
Handle<JSTypedArray> const array =
Handle<JSTypedArray>::cast(mbase.Value().handle());
array->GetBuffer()->set_is_neuterable(false);
BufferAccess const access(array->type());
size_t const k = ElementSizeLog2Of(access.machine_type());
double const byte_length = array->byte_length()->Number();
CHECK_LT(k, arraysize(shifted_int32_ranges_));
if (IsExternalArrayElementsKind(array->map()->elements_kind()) &&
key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
// JSLoadProperty(typed-array, int32)
Handle<ExternalArray> elements =
Handle<ExternalArray>::cast(handle(array->elements()));
Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
Node* length = jsgraph()->Constant(byte_length);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
// Check if we can avoid the bounds check.
if (key_type->Min() >= 0 && key_type->Max() < array->length()->Number()) {
Node* load = graph()->NewNode(
simplified()->LoadElement(
AccessBuilder::ForTypedArrayElement(array->type(), true)),
buffer, key, effect, control);
if (!array->GetBuffer()->was_neutered()) {
array->GetBuffer()->set_is_neuterable(false);
BufferAccess const access(array->type());
size_t const k = ElementSizeLog2Of(access.machine_type());
double const byte_length = array->byte_length()->Number();
CHECK_LT(k, arraysize(shifted_int32_ranges_));
if (IsExternalArrayElementsKind(array->map()->elements_kind()) &&
key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
// JSLoadProperty(typed-array, int32)
Handle<ExternalArray> elements =
Handle<ExternalArray>::cast(handle(array->elements()));
Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
Node* length = jsgraph()->Constant(byte_length);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
// Check if we can avoid the bounds check.
if (key_type->Min() >= 0 &&
key_type->Max() < array->length()->Number()) {
Node* load = graph()->NewNode(
simplified()->LoadElement(
AccessBuilder::ForTypedArrayElement(array->type(), true)),
buffer, key, effect, control);
return ReplaceEagerly(node, load);
}
// Compute byte offset.
Node* offset = Word32Shl(key, static_cast<int>(k));
Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer,
offset, length, effect, control);
return ReplaceEagerly(node, load);
}
// Compute byte offset.
Node* offset = Word32Shl(key, static_cast<int>(k));
Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer,
offset, length, effect, control);
return ReplaceEagerly(node, load);
}
}
return NoChange();
......@@ -874,75 +875,76 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
Node* value = NodeProperties::GetValueInput(node, 2);
Type* key_type = NodeProperties::GetBounds(key).upper;
Type* value_type = NodeProperties::GetBounds(value).upper;
// TODO(mstarzinger): This lowering is not correct if:
// a) The typed array or its buffer is neutered.
HeapObjectMatcher<Object> mbase(base);
if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) {
Handle<JSTypedArray> const array =
Handle<JSTypedArray>::cast(mbase.Value().handle());
array->GetBuffer()->set_is_neuterable(false);
BufferAccess const access(array->type());
size_t const k = ElementSizeLog2Of(access.machine_type());
double const byte_length = array->byte_length()->Number();
CHECK_LT(k, arraysize(shifted_int32_ranges_));
if (IsExternalArrayElementsKind(array->map()->elements_kind()) &&
access.external_array_type() != kExternalUint8ClampedArray &&
key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
// JSLoadProperty(typed-array, int32)
Handle<ExternalArray> elements =
Handle<ExternalArray>::cast(handle(array->elements()));
Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
Node* length = jsgraph()->Constant(byte_length);
Node* context = NodeProperties::GetContextInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
// Convert to a number first.
if (!value_type->Is(Type::Number())) {
Reduction number_reduction = ReduceJSToNumberInput(value);
if (number_reduction.Changed()) {
value = number_reduction.replacement();
} else {
Node* frame_state_for_to_number =
NodeProperties::GetFrameStateInput(node, 1);
value = effect =
graph()->NewNode(javascript()->ToNumber(), value, context,
frame_state_for_to_number, effect, control);
if (!array->GetBuffer()->was_neutered()) {
array->GetBuffer()->set_is_neuterable(false);
BufferAccess const access(array->type());
size_t const k = ElementSizeLog2Of(access.machine_type());
double const byte_length = array->byte_length()->Number();
CHECK_LT(k, arraysize(shifted_int32_ranges_));
if (IsExternalArrayElementsKind(array->map()->elements_kind()) &&
access.external_array_type() != kExternalUint8ClampedArray &&
key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
// JSLoadProperty(typed-array, int32)
Handle<ExternalArray> elements =
Handle<ExternalArray>::cast(handle(array->elements()));
Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
Node* length = jsgraph()->Constant(byte_length);
Node* context = NodeProperties::GetContextInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
// Convert to a number first.
if (!value_type->Is(Type::Number())) {
Reduction number_reduction = ReduceJSToNumberInput(value);
if (number_reduction.Changed()) {
value = number_reduction.replacement();
} else {
Node* frame_state_for_to_number =
NodeProperties::GetFrameStateInput(node, 1);
value = effect =
graph()->NewNode(javascript()->ToNumber(), value, context,
frame_state_for_to_number, effect, control);
}
}
}
// For integer-typed arrays, convert to the integer type.
if (TypeOf(access.machine_type()) == kTypeInt32 &&
!value_type->Is(Type::Signed32())) {
value = graph()->NewNode(simplified()->NumberToInt32(), value);
} else if (TypeOf(access.machine_type()) == kTypeUint32 &&
!value_type->Is(Type::Unsigned32())) {
value = graph()->NewNode(simplified()->NumberToUint32(), value);
}
// Check if we can avoid the bounds check.
if (key_type->Min() >= 0 && key_type->Max() < array->length()->Number()) {
node->set_op(simplified()->StoreElement(
AccessBuilder::ForTypedArrayElement(array->type(), true)));
// For integer-typed arrays, convert to the integer type.
if (TypeOf(access.machine_type()) == kTypeInt32 &&
!value_type->Is(Type::Signed32())) {
value = graph()->NewNode(simplified()->NumberToInt32(), value);
} else if (TypeOf(access.machine_type()) == kTypeUint32 &&
!value_type->Is(Type::Unsigned32())) {
value = graph()->NewNode(simplified()->NumberToUint32(), value);
}
// Check if we can avoid the bounds check.
if (key_type->Min() >= 0 &&
key_type->Max() < array->length()->Number()) {
node->set_op(simplified()->StoreElement(
AccessBuilder::ForTypedArrayElement(array->type(), true)));
node->ReplaceInput(0, buffer);
DCHECK_EQ(key, node->InputAt(1));
node->ReplaceInput(2, value);
node->ReplaceInput(3, effect);
node->ReplaceInput(4, control);
node->TrimInputCount(5);
RelaxControls(node);
return Changed(node);
}
// Compute byte offset.
Node* offset = Word32Shl(key, static_cast<int>(k));
// Turn into a StoreBuffer operation.
node->set_op(simplified()->StoreBuffer(access));
node->ReplaceInput(0, buffer);
DCHECK_EQ(key, node->InputAt(1));
node->ReplaceInput(2, value);
node->ReplaceInput(3, effect);
node->ReplaceInput(4, control);
node->TrimInputCount(5);
node->ReplaceInput(1, offset);
node->ReplaceInput(2, length);
node->ReplaceInput(3, value);
node->ReplaceInput(4, effect);
node->ReplaceInput(5, control);
node->TrimInputCount(6);
RelaxControls(node);
return Changed(node);
}
// Compute byte offset.
Node* offset = Word32Shl(key, static_cast<int>(k));
// Turn into a StoreBuffer operation.
node->set_op(simplified()->StoreBuffer(access));
node->ReplaceInput(0, buffer);
node->ReplaceInput(1, offset);
node->ReplaceInput(2, length);
node->ReplaceInput(3, value);
node->ReplaceInput(4, effect);
node->ReplaceInput(5, control);
node->TrimInputCount(6);
RelaxControls(node);
return Changed(node);
}
}
return NoChange();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment