Commit a50baa24 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[turbofan] Reduce DataView access code duplication.

Part of https://chromium-review.googlesource.com/1231994 that landed
earlier, but was reverted due to breakage. Landing this cleanup
separately instead.

Drive-by-fix: Also add test coverage for the cases that weren't covered
properly (according to the test coverage bot).

Bug: chromium:225811, v8:8015
Change-Id: I9c13ed5fcf0ba9e6b190489e15df86970eafdc13
Reviewed-on: https://chromium-review.googlesource.com/1236213Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56087}
parent 7add73d4
......@@ -3470,53 +3470,53 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
node, JS_DATA_VIEW_TYPE,
AccessBuilder::ForJSArrayBufferViewByteOffset());
case Builtins::kDataViewPrototypeGetUint8:
return ReduceDataViewPrototypeGet(node,
ExternalArrayType::kExternalUint8Array);
return ReduceDataViewAccess(node, DataViewAccess::kGet,
ExternalArrayType::kExternalUint8Array);
case Builtins::kDataViewPrototypeGetInt8:
return ReduceDataViewPrototypeGet(node,
ExternalArrayType::kExternalInt8Array);
return ReduceDataViewAccess(node, DataViewAccess::kGet,
ExternalArrayType::kExternalInt8Array);
case Builtins::kDataViewPrototypeGetUint16:
return ReduceDataViewPrototypeGet(
node, ExternalArrayType::kExternalUint16Array);
return ReduceDataViewAccess(node, DataViewAccess::kGet,
ExternalArrayType::kExternalUint16Array);
case Builtins::kDataViewPrototypeGetInt16:
return ReduceDataViewPrototypeGet(node,
ExternalArrayType::kExternalInt16Array);
return ReduceDataViewAccess(node, DataViewAccess::kGet,
ExternalArrayType::kExternalInt16Array);
case Builtins::kDataViewPrototypeGetUint32:
return ReduceDataViewPrototypeGet(
node, ExternalArrayType::kExternalUint32Array);
return ReduceDataViewAccess(node, DataViewAccess::kGet,
ExternalArrayType::kExternalUint32Array);
case Builtins::kDataViewPrototypeGetInt32:
return ReduceDataViewPrototypeGet(node,
ExternalArrayType::kExternalInt32Array);
return ReduceDataViewAccess(node, DataViewAccess::kGet,
ExternalArrayType::kExternalInt32Array);
case Builtins::kDataViewPrototypeGetFloat32:
return ReduceDataViewPrototypeGet(
node, ExternalArrayType::kExternalFloat32Array);
return ReduceDataViewAccess(node, DataViewAccess::kGet,
ExternalArrayType::kExternalFloat32Array);
case Builtins::kDataViewPrototypeGetFloat64:
return ReduceDataViewPrototypeGet(
node, ExternalArrayType::kExternalFloat64Array);
return ReduceDataViewAccess(node, DataViewAccess::kGet,
ExternalArrayType::kExternalFloat64Array);
case Builtins::kDataViewPrototypeSetUint8:
return ReduceDataViewPrototypeSet(node,
ExternalArrayType::kExternalUint8Array);
return ReduceDataViewAccess(node, DataViewAccess::kSet,
ExternalArrayType::kExternalUint8Array);
case Builtins::kDataViewPrototypeSetInt8:
return ReduceDataViewPrototypeSet(node,
ExternalArrayType::kExternalInt8Array);
return ReduceDataViewAccess(node, DataViewAccess::kSet,
ExternalArrayType::kExternalInt8Array);
case Builtins::kDataViewPrototypeSetUint16:
return ReduceDataViewPrototypeSet(
node, ExternalArrayType::kExternalUint16Array);
return ReduceDataViewAccess(node, DataViewAccess::kSet,
ExternalArrayType::kExternalUint16Array);
case Builtins::kDataViewPrototypeSetInt16:
return ReduceDataViewPrototypeSet(node,
ExternalArrayType::kExternalInt16Array);
return ReduceDataViewAccess(node, DataViewAccess::kSet,
ExternalArrayType::kExternalInt16Array);
case Builtins::kDataViewPrototypeSetUint32:
return ReduceDataViewPrototypeSet(
node, ExternalArrayType::kExternalUint32Array);
return ReduceDataViewAccess(node, DataViewAccess::kSet,
ExternalArrayType::kExternalUint32Array);
case Builtins::kDataViewPrototypeSetInt32:
return ReduceDataViewPrototypeSet(node,
ExternalArrayType::kExternalInt32Array);
return ReduceDataViewAccess(node, DataViewAccess::kSet,
ExternalArrayType::kExternalInt32Array);
case Builtins::kDataViewPrototypeSetFloat32:
return ReduceDataViewPrototypeSet(
node, ExternalArrayType::kExternalFloat32Array);
return ReduceDataViewAccess(node, DataViewAccess::kSet,
ExternalArrayType::kExternalFloat32Array);
case Builtins::kDataViewPrototypeSetFloat64:
return ReduceDataViewPrototypeSet(
node, ExternalArrayType::kExternalFloat64Array);
return ReduceDataViewAccess(node, DataViewAccess::kSet,
ExternalArrayType::kExternalFloat64Array);
case Builtins::kTypedArrayPrototypeByteLength:
return ReduceArrayBufferViewAccessor(
node, JS_TYPED_ARRAY_TYPE,
......@@ -6784,164 +6784,33 @@ uint32_t ExternalArrayElementSize(const ExternalArrayType element_type) {
}
} // namespace
Reduction JSCallReducer::ReduceDataViewPrototypeGet(
Node* node, ExternalArrayType element_type) {
Reduction JSCallReducer::ReduceDataViewAccess(Node* node, DataViewAccess access,
ExternalArrayType element_type) {
size_t const element_size = ExternalArrayElementSize(element_type);
CallParameters const& p = CallParametersOf(node->op());
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* receiver = NodeProperties::GetValueInput(node, 1);
if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) {
return NoChange();
}
Node* offset = node->op()->ValueInputCount() > 2
? NodeProperties::GetValueInput(node, 2)
: jsgraph()->ZeroConstant();
Node* is_little_endian = node->op()->ValueInputCount() > 3
? NodeProperties::GetValueInput(node, 3)
: jsgraph()->FalseConstant();
// Only do stuff if the {receiver} is really a DataView.
if (NodeProperties::HasInstanceTypeWitness(isolate(), receiver, effect,
JS_DATA_VIEW_TYPE)) {
// Check that the {offset} is within range for the {receiver}.
HeapObjectMatcher m(receiver);
if (m.HasValue()) {
// We only deal with DataViews here whose [[ByteLength]] is at least
// {element_size} and less than 2^31-{element_size}.
Handle<JSDataView> dataview = Handle<JSDataView>::cast(m.Value());
if (dataview->byte_length() < element_size ||
dataview->byte_length() - element_size > kMaxInt) {
return NoChange();
}
// The {receiver}s [[ByteOffset]] must be within Unsigned31 range.
if (dataview->byte_offset() > kMaxInt) {
return NoChange();
}
// Check that the {offset} is within range of the {byte_length}.
Node* byte_length =
jsgraph()->Constant(dataview->byte_length() - (element_size - 1));
offset = effect =
graph()->NewNode(simplified()->CheckBounds(p.feedback()), offset,
byte_length, effect, control);
// Add the [[ByteOffset]] to compute the effective offset.
Node* byte_offset = jsgraph()->Constant(dataview->byte_offset());
offset = graph()->NewNode(simplified()->NumberAdd(), offset, byte_offset);
} else {
// We only deal with DataViews here that have Smi [[ByteLength]]s.
Node* byte_length = effect =
graph()->NewNode(simplified()->LoadField(
AccessBuilder::ForJSArrayBufferViewByteLength()),
receiver, effect, control);
byte_length = effect = graph()->NewNode(
simplified()->CheckSmi(p.feedback()), byte_length, effect, control);
// Check that the {offset} is within range of the {byte_length}.
offset = effect =
graph()->NewNode(simplified()->CheckBounds(p.feedback()), offset,
byte_length, effect, control);
if (element_size > 0) {
// For non-byte accesses we also need to check that the {offset}
// plus the {element_size}-1 fits within the given {byte_length}.
Node* end_offset =
graph()->NewNode(simplified()->NumberAdd(), offset,
jsgraph()->Constant(element_size - 1));
effect = graph()->NewNode(simplified()->CheckBounds(p.feedback()),
end_offset, byte_length, effect, control);
}
// The {receiver}s [[ByteOffset]] also needs to be a (positive) Smi.
Node* byte_offset = effect =
graph()->NewNode(simplified()->LoadField(
AccessBuilder::ForJSArrayBufferViewByteOffset()),
receiver, effect, control);
byte_offset = effect = graph()->NewNode(
simplified()->CheckSmi(p.feedback()), byte_offset, effect, control);
// Compute the buffer index at which we'll read.
offset = graph()->NewNode(simplified()->NumberAdd(), offset, byte_offset);
}
// Coerce {is_little_endian} to boolean.
is_little_endian =
graph()->NewNode(simplified()->ToBoolean(), is_little_endian);
// Get the underlying buffer and check that it has not been neutered.
Node* buffer = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForJSArrayBufferViewBuffer()),
receiver, effect, control);
if (isolate()->IsArrayBufferNeuteringIntact()) {
// Add a code dependency so we are deoptimized in case an ArrayBuffer
// gets neutered.
dependencies()->DependOnProtector(PropertyCellRef(
js_heap_broker(), factory()->array_buffer_neutering_protector()));
} else {
// Bail out if the {buffer} was neutered.
Node* buffer_bit_field = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForJSArrayBufferBitField()),
buffer, effect, control);
Node* check = graph()->NewNode(
simplified()->NumberEqual(),
graph()->NewNode(
simplified()->NumberBitwiseAnd(), buffer_bit_field,
jsgraph()->Constant(JSArrayBuffer::WasNeuteredBit::kMask)),
jsgraph()->ZeroConstant());
effect = graph()->NewNode(
simplified()->CheckIf(DeoptimizeReason::kArrayBufferWasNeutered,
p.feedback()),
check, effect, control);
}
// Get the buffer's backing store.
Node* backing_store = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForJSArrayBufferBackingStore()),
buffer, effect, control);
// Perform the load.
Node* value = effect = graph()->NewNode(
simplified()->LoadDataViewElement(element_type), buffer, backing_store,
offset, is_little_endian, effect, control);
// Continue on the regular path.
ReplaceWithValue(node, value, effect, control);
return Changed(value);
}
return NoChange();
}
Reduction JSCallReducer::ReduceDataViewPrototypeSet(
Node* node, ExternalArrayType element_type) {
size_t const element_size = ExternalArrayElementSize(element_type);
CallParameters const& p = CallParametersOf(node->op());
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* receiver = NodeProperties::GetValueInput(node, 1);
Node* value = (access == DataViewAccess::kGet)
? nullptr
: (node->op()->ValueInputCount() > 3
? NodeProperties::GetValueInput(node, 3)
: jsgraph()->ZeroConstant());
Node* is_little_endian = (access == DataViewAccess::kGet)
? (node->op()->ValueInputCount() > 3
? NodeProperties::GetValueInput(node, 3)
: jsgraph()->FalseConstant())
: (node->op()->ValueInputCount() > 4
? NodeProperties::GetValueInput(node, 4)
: jsgraph()->FalseConstant());
if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) {
return NoChange();
}
Node* offset = node->op()->ValueInputCount() > 2
? NodeProperties::GetValueInput(node, 2)
: jsgraph()->ZeroConstant();
Node* value = node->op()->ValueInputCount() > 3
? NodeProperties::GetValueInput(node, 3)
: jsgraph()->ZeroConstant();
Node* is_little_endian = node->op()->ValueInputCount() > 4
? NodeProperties::GetValueInput(node, 4)
: jsgraph()->FalseConstant();
// Only do stuff if the {receiver} is really a DataView.
if (NodeProperties::HasInstanceTypeWitness(isolate(), receiver, effect,
JS_DATA_VIEW_TYPE)) {
......@@ -7012,10 +6881,12 @@ Reduction JSCallReducer::ReduceDataViewPrototypeSet(
graph()->NewNode(simplified()->ToBoolean(), is_little_endian);
// Coerce {value} to Number.
value = effect = graph()->NewNode(
simplified()->SpeculativeToNumber(NumberOperationHint::kNumberOrOddball,
p.feedback()),
value, effect, control);
if (access == DataViewAccess::kSet) {
value = effect = graph()->NewNode(
simplified()->SpeculativeToNumber(
NumberOperationHint::kNumberOrOddball, p.feedback()),
value, effect, control);
}
// Get the underlying buffer and check that it has not been neutered.
Node* buffer = effect = graph()->NewNode(
......@@ -7049,12 +6920,21 @@ Reduction JSCallReducer::ReduceDataViewPrototypeSet(
simplified()->LoadField(AccessBuilder::ForJSArrayBufferBackingStore()),
buffer, effect, control);
// Perform the store.
effect = graph()->NewNode(simplified()->StoreDataViewElement(element_type),
buffer, backing_store, offset, value,
is_little_endian, effect, control);
Node* value = jsgraph()->UndefinedConstant();
switch (access) {
case DataViewAccess::kGet:
// Perform the load.
value = effect = graph()->NewNode(
simplified()->LoadDataViewElement(element_type), buffer,
backing_store, offset, is_little_endian, effect, control);
break;
case DataViewAccess::kSet:
// Perform the store.
effect = graph()->NewNode(
simplified()->StoreDataViewElement(element_type), buffer,
backing_store, offset, value, is_little_endian, effect, control);
value = jsgraph()->UndefinedConstant();
break;
}
// Continue on the regular path.
ReplaceWithValue(node, value, effect, control);
......
......@@ -182,10 +182,9 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
InstanceType instance_type,
FieldAccess const& access);
Reduction ReduceDataViewPrototypeGet(Node* node,
ExternalArrayType element_type);
Reduction ReduceDataViewPrototypeSet(Node* node,
ExternalArrayType element_type);
enum class DataViewAccess { kGet, kSet };
Reduction ReduceDataViewAccess(Node* node, DataViewAccess access,
ExternalArrayType element_type);
Reduction ReduceDatePrototypeGetTime(Node* node);
Reduction ReduceDateNow(Node* node);
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Test DataView.prototype.getInt8()/setInt8() for constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setInt8(0, 42);
dv.setInt8(1, 24);
function foo(i) {
const x = dv.getInt8(i);
dv.setInt8(i, x+1);
return x;
}
assertEquals(42, foo(0));
assertEquals(24, foo(1));
assertEquals(43, foo(0));
assertEquals(25, foo(1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(0));
assertEquals(26, foo(1));
})();
// Test DataView.prototype.getUint8()/setUint8() for constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setUint8(0, 42);
dv.setUint8(1, 24);
function foo(i) {
const x = dv.getUint8(i);
dv.setUint8(i, x+1);
return x;
}
assertEquals(42, foo(0));
assertEquals(24, foo(1));
assertEquals(43, foo(0));
assertEquals(25, foo(1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(0));
assertEquals(26, foo(1));
})();
// Test DataView.prototype.getInt16()/setInt16() for constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setInt16(0, 42, true);
dv.setInt16(2, 24, true);
function foo(i) {
const x = dv.getInt16(i, true);
dv.setInt16(i, x+1, true);
return x;
}
assertEquals(42, foo(0));
assertEquals(24, foo(2));
assertEquals(43, foo(0));
assertEquals(25, foo(2));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(0));
assertEquals(26, foo(2));
})();
// Test DataView.prototype.getUint16()/setUint16() for constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setUint16(0, 42, true);
dv.setUint16(2, 24, true);
function foo(i) {
const x = dv.getUint16(i, true);
dv.setUint16(i, x+1, true);
return x;
}
assertEquals(42, foo(0));
assertEquals(24, foo(2));
assertEquals(43, foo(0));
assertEquals(25, foo(2));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(0));
assertEquals(26, foo(2));
})();
// Test DataView.prototype.getInt32()/setInt32() for constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setInt32(0, 42, true);
dv.setInt32(4, 24, true);
function foo(i) {
const x = dv.getInt32(i, true);
dv.setInt32(i, x+1, true);
return x;
}
assertEquals(42, foo(0));
assertEquals(24, foo(4));
assertEquals(43, foo(0));
assertEquals(25, foo(4));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(0));
assertEquals(26, foo(4));
})();
// Test DataView.prototype.getUint32()/setUint32() for constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setUint32(0, 42, true);
dv.setUint32(4, 24, true);
function foo(i) {
const x = dv.getUint32(i, true);
dv.setUint32(i, x+1, true);
return x;
}
assertEquals(42, foo(0));
assertEquals(24, foo(4));
assertEquals(43, foo(0));
assertEquals(25, foo(4));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(0));
assertEquals(26, foo(4));
})();
// Test DataView.prototype.getFloat32()/setFloat32() for constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setFloat32(0, 42, true);
dv.setFloat32(4, 24, true);
function foo(i) {
const x = dv.getFloat32(i, true);
dv.setFloat32(i, x+1, true);
return x;
}
assertEquals(42, foo(0));
assertEquals(24, foo(4));
assertEquals(43, foo(0));
assertEquals(25, foo(4));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(0));
assertEquals(26, foo(4));
})();
// Test DataView.prototype.getFloat64()/setFloat64() for constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setFloat64(0, 42, true);
dv.setFloat64(8, 24, true);
function foo(i) {
const x = dv.getFloat64(i, true);
dv.setFloat64(i, x+1, true);
return x;
}
assertEquals(42, foo(0));
assertEquals(24, foo(8));
assertEquals(43, foo(0));
assertEquals(25, foo(8));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(0));
assertEquals(26, foo(8));
})();
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --opt --noalways-opt
// Invalidate the neutering protector.
%ArrayBufferNeuter(new ArrayBuffer(1));
// Check DataView.prototype.getInt8() optimization.
(function() {
const ab = new ArrayBuffer(1);
const dv = new DataView(ab);
function foo(dv) {
return dv.getInt8(0);
}
assertEquals(0, foo(dv));
assertEquals(0, foo(dv));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(dv));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.getUint8() optimization.
(function() {
const ab = new ArrayBuffer(1);
const dv = new DataView(ab);
function foo(dv) {
return dv.getUint8(0);
}
assertEquals(0, foo(dv));
assertEquals(0, foo(dv));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(dv));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.getInt16() optimization.
(function() {
const ab = new ArrayBuffer(2);
const dv = new DataView(ab);
function foo(dv) {
return dv.getInt16(0, true);
}
assertEquals(0, foo(dv));
assertEquals(0, foo(dv));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(dv));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.getUint16() optimization.
(function() {
const ab = new ArrayBuffer(2);
const dv = new DataView(ab);
function foo(dv) {
return dv.getUint16(0, true);
}
assertEquals(0, foo(dv));
assertEquals(0, foo(dv));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(dv));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.getInt32() optimization.
(function() {
const ab = new ArrayBuffer(4);
const dv = new DataView(ab);
function foo(dv) {
return dv.getInt32(0, true);
}
assertEquals(0, foo(dv));
assertEquals(0, foo(dv));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(dv));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.getUint32() optimization.
(function() {
const ab = new ArrayBuffer(4);
const dv = new DataView(ab);
function foo(dv) {
return dv.getUint32(0, true);
}
assertEquals(0, foo(dv));
assertEquals(0, foo(dv));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(dv));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.getFloat32() optimization.
(function() {
const ab = new ArrayBuffer(4);
const dv = new DataView(ab);
function foo(dv) {
return dv.getFloat32(0, true);
}
assertEquals(0, foo(dv));
assertEquals(0, foo(dv));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(dv));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.getFloat64() optimization.
(function() {
const ab = new ArrayBuffer(8);
const dv = new DataView(ab);
function foo(dv) {
return dv.getFloat64(0, true);
}
assertEquals(0, foo(dv));
assertEquals(0, foo(dv));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(dv));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.setInt8() optimization.
(function() {
const ab = new ArrayBuffer(1);
const dv = new DataView(ab);
function foo(dv, x) {
return dv.setInt8(0, x);
}
assertEquals(undefined, foo(dv, 1));
assertEquals(1, dv.getInt8(0));
assertEquals(undefined, foo(dv, 2));
assertEquals(2, dv.getInt8(0));
%OptimizeFunctionOnNextCall(foo);
assertEquals(undefined, foo(dv, 3));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv, 4), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv, 5), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.setUint8() optimization.
(function() {
const ab = new ArrayBuffer(1);
const dv = new DataView(ab);
function foo(dv, x) {
return dv.setUint8(0, x);
}
assertEquals(undefined, foo(dv, 1));
assertEquals(1, dv.getUint8(0));
assertEquals(undefined, foo(dv, 2));
assertEquals(2, dv.getUint8(0));
%OptimizeFunctionOnNextCall(foo);
assertEquals(undefined, foo(dv, 3));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv, 4), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv, 5), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.setInt16() optimization.
(function() {
const ab = new ArrayBuffer(2);
const dv = new DataView(ab);
function foo(dv, x) {
return dv.setInt16(0, x, true);
}
assertEquals(undefined, foo(dv, 1));
assertEquals(1, dv.getInt16(0, true));
assertEquals(undefined, foo(dv, 2));
assertEquals(2, dv.getInt16(0, true));
%OptimizeFunctionOnNextCall(foo);
assertEquals(undefined, foo(dv, 3));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv, 4), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv, 5), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.setUint16() optimization.
(function() {
const ab = new ArrayBuffer(2);
const dv = new DataView(ab);
function foo(dv, x) {
return dv.setUint16(0, x, true);
}
assertEquals(undefined, foo(dv, 1));
assertEquals(1, dv.getUint16(0, true));
assertEquals(undefined, foo(dv, 2));
assertEquals(2, dv.getUint16(0, true));
%OptimizeFunctionOnNextCall(foo);
assertEquals(undefined, foo(dv, 3));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv, 4), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv, 5), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.setInt32() optimization.
(function() {
const ab = new ArrayBuffer(4);
const dv = new DataView(ab);
function foo(dv, x) {
return dv.setInt32(0, x, true);
}
assertEquals(undefined, foo(dv, 1));
assertEquals(1, dv.getInt32(0, true));
assertEquals(undefined, foo(dv, 2));
assertEquals(2, dv.getInt32(0, true));
%OptimizeFunctionOnNextCall(foo);
assertEquals(undefined, foo(dv, 3));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv, 4), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv, 5), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.setUint32() optimization.
(function() {
const ab = new ArrayBuffer(4);
const dv = new DataView(ab);
function foo(dv, x) {
return dv.setUint32(0, x, true);
}
assertEquals(undefined, foo(dv, 1));
assertEquals(1, dv.getUint32(0, true));
assertEquals(undefined, foo(dv, 2));
assertEquals(2, dv.getUint32(0, true));
%OptimizeFunctionOnNextCall(foo);
assertEquals(undefined, foo(dv, 3));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv, 4), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv, 5), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.setFloat32() optimization.
(function() {
const ab = new ArrayBuffer(4);
const dv = new DataView(ab);
function foo(dv, x) {
return dv.setFloat32(0, x, true);
}
assertEquals(undefined, foo(dv, 1));
assertEquals(1, dv.getFloat32(0, true));
assertEquals(undefined, foo(dv, 2));
assertEquals(2, dv.getFloat32(0, true));
%OptimizeFunctionOnNextCall(foo);
assertEquals(undefined, foo(dv, 3));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv, 4), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv, 5), TypeError);
assertOptimized(foo);
})();
// Check DataView.prototype.setFloat64() optimization.
(function() {
const ab = new ArrayBuffer(8);
const dv = new DataView(ab);
function foo(dv, x) {
return dv.setFloat64(0, x, true);
}
assertEquals(undefined, foo(dv, 1));
assertEquals(1, dv.getFloat64(0, true));
assertEquals(undefined, foo(dv, 2));
assertEquals(2, dv.getFloat64(0, true));
%OptimizeFunctionOnNextCall(foo);
assertEquals(undefined, foo(dv, 3));
assertOptimized(foo);
%ArrayBufferNeuter(ab);
assertThrows(() => foo(dv, 4), TypeError);
assertUnoptimized(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(dv, 5), TypeError);
assertOptimized(foo);
})();
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Test DataView.prototype.getInt8()/setInt8() for non-constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setInt8(0, 42);
dv.setInt8(1, 24);
function foo(dv, i) {
const x = dv.getInt8(i);
dv.setInt8(i, x+1);
return x;
}
assertEquals(42, foo(dv, 0));
assertEquals(24, foo(dv, 1));
assertEquals(43, foo(dv, 0));
assertEquals(25, foo(dv, 1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(dv, 0));
assertEquals(26, foo(dv, 1));
})();
// Test DataView.prototype.getUint8()/setUint8() for non-constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setUint8(0, 42);
dv.setUint8(1, 24);
function foo(dv, i) {
const x = dv.getUint8(i);
dv.setUint8(i, x+1);
return x;
}
assertEquals(42, foo(dv, 0));
assertEquals(24, foo(dv, 1));
assertEquals(43, foo(dv, 0));
assertEquals(25, foo(dv, 1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(dv, 0));
assertEquals(26, foo(dv, 1));
})();
// Test DataView.prototype.getInt16()/setInt16() for non-constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setInt16(0, 42, true);
dv.setInt16(2, 24, true);
function foo(dv, i) {
const x = dv.getInt16(i, true);
dv.setInt16(i, x+1, true);
return x;
}
assertEquals(42, foo(dv, 0));
assertEquals(24, foo(dv, 2));
assertEquals(43, foo(dv, 0));
assertEquals(25, foo(dv, 2));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(dv, 0));
assertEquals(26, foo(dv, 2));
})();
// Test DataView.prototype.getUint16()/setUint16() for non-constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setUint16(0, 42, true);
dv.setUint16(2, 24, true);
function foo(dv, i) {
const x = dv.getUint16(i, true);
dv.setUint16(i, x+1, true);
return x;
}
assertEquals(42, foo(dv, 0));
assertEquals(24, foo(dv, 2));
assertEquals(43, foo(dv, 0));
assertEquals(25, foo(dv, 2));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(dv, 0));
assertEquals(26, foo(dv, 2));
})();
// Test DataView.prototype.getInt32()/setInt32() for non-constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setInt32(0, 42, true);
dv.setInt32(4, 24, true);
function foo(dv, i) {
const x = dv.getInt32(i, true);
dv.setInt32(i, x+1, true);
return x;
}
assertEquals(42, foo(dv, 0));
assertEquals(24, foo(dv, 4));
assertEquals(43, foo(dv, 0));
assertEquals(25, foo(dv, 4));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(dv, 0));
assertEquals(26, foo(dv, 4));
})();
// Test DataView.prototype.getUint32()/setUint32() for non-constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setUint32(0, 42, true);
dv.setUint32(4, 24, true);
function foo(dv, i) {
const x = dv.getUint32(i, true);
dv.setUint32(i, x+1, true);
return x;
}
assertEquals(42, foo(dv, 0));
assertEquals(24, foo(dv, 4));
assertEquals(43, foo(dv, 0));
assertEquals(25, foo(dv, 4));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(dv, 0));
assertEquals(26, foo(dv, 4));
})();
// Test DataView.prototype.getFloat32()/setFloat32() for non-constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setFloat32(0, 42, true);
dv.setFloat32(4, 24, true);
function foo(dv, i) {
const x = dv.getFloat32(i, true);
dv.setFloat32(i, x+1, true);
return x;
}
assertEquals(42, foo(dv, 0));
assertEquals(24, foo(dv, 4));
assertEquals(43, foo(dv, 0));
assertEquals(25, foo(dv, 4));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(dv, 0));
assertEquals(26, foo(dv, 4));
})();
// Test DataView.prototype.getFloat64()/setFloat64() for non-constant DataViews.
(function() {
const dv = new DataView(new ArrayBuffer(1024));
dv.setFloat64(0, 42, true);
dv.setFloat64(8, 24, true);
function foo(dv, i) {
const x = dv.getFloat64(i, true);
dv.setFloat64(i, x+1, true);
return x;
}
assertEquals(42, foo(dv, 0));
assertEquals(24, foo(dv, 8));
assertEquals(43, foo(dv, 0));
assertEquals(25, foo(dv, 8));
%OptimizeFunctionOnNextCall(foo);
assertEquals(44, foo(dv, 0));
assertEquals(26, foo(dv, 8));
})();
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