[turbofan] Fix incorrect size shift computation for DataViews
Bug: v8:11111, chromium:1380398, chromium:1380990 Change-Id: I99ee88341d1119d1372210741ddccb0e2cd33bf7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4002688 Auto-Submit: Nico Hartmann <nicohartmann@chromium.org> Commit-Queue: Nico Hartmann <nicohartmann@chromium.org> Commit-Queue: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/main@{#84045}
This commit is contained in:
parent
46a5e5a750
commit
2caf5d18db
@ -470,9 +470,14 @@ Node* JSGraphAssembler::StringCharCodeAt(TNode<String> string,
|
||||
class ArrayBufferViewAccessBuilder {
|
||||
public:
|
||||
explicit ArrayBufferViewAccessBuilder(JSGraphAssembler* assembler,
|
||||
InstanceType instance_type,
|
||||
std::set<ElementsKind> candidates)
|
||||
: assembler_(assembler), candidates_(std::move(candidates)) {
|
||||
: assembler_(assembler),
|
||||
instance_type_(instance_type),
|
||||
candidates_(std::move(candidates)) {
|
||||
DCHECK_NOT_NULL(assembler_);
|
||||
DCHECK(instance_type_ == JS_DATA_VIEW_TYPE ||
|
||||
instance_type_ == JS_TYPED_ARRAY_TYPE);
|
||||
}
|
||||
|
||||
bool maybe_rab_gsab() const {
|
||||
@ -483,6 +488,7 @@ class ArrayBufferViewAccessBuilder {
|
||||
}
|
||||
|
||||
base::Optional<int> TryComputeStaticElementShift() {
|
||||
if (instance_type_ == JS_DATA_VIEW_TYPE) return 0;
|
||||
if (candidates_.empty()) return base::nullopt;
|
||||
int shift = ElementsKindToShiftSize(*candidates_.begin());
|
||||
if (!base::all_of(candidates_, [shift](auto e) {
|
||||
@ -494,6 +500,7 @@ class ArrayBufferViewAccessBuilder {
|
||||
}
|
||||
|
||||
base::Optional<int> TryComputeStaticElementSize() {
|
||||
if (instance_type_ == JS_DATA_VIEW_TYPE) return 1;
|
||||
if (candidates_.empty()) return base::nullopt;
|
||||
int size = ElementsKindToByteSize(*candidates_.begin());
|
||||
if (!base::all_of(candidates_, [size](auto e) {
|
||||
@ -540,6 +547,7 @@ class ArrayBufferViewAccessBuilder {
|
||||
if (auto size_opt = TryComputeStaticElementSize()) {
|
||||
element_size = a.Uint32Constant(*size_opt);
|
||||
} else {
|
||||
DCHECK_EQ(instance_type_, JS_TYPED_ARRAY_TYPE);
|
||||
TNode<Map> typed_array_map = a.LoadField<Map>(
|
||||
AccessBuilder::ForMap(WriteBarrierKind::kNoWriteBarrier), view);
|
||||
TNode<Uint32T> elements_kind = a.LoadElementsKind(typed_array_map);
|
||||
@ -682,6 +690,7 @@ class ArrayBufferViewAccessBuilder {
|
||||
return TNode<UintPtrT>::UncheckedCast(
|
||||
a.WordAnd(byte_size, a.UintPtrConstant(all_bits << (*shift_opt))));
|
||||
}
|
||||
DCHECK_EQ(instance_type_, JS_TYPED_ARRAY_TYPE);
|
||||
TNode<Map> typed_array_map = a.LoadField<Map>(
|
||||
AccessBuilder::ForMap(WriteBarrierKind::kNoWriteBarrier), view);
|
||||
TNode<Uint32T> elements_kind = a.LoadElementsKind(typed_array_map);
|
||||
@ -751,13 +760,14 @@ class ArrayBufferViewAccessBuilder {
|
||||
}
|
||||
|
||||
JSGraphAssembler* assembler_;
|
||||
InstanceType instance_type_;
|
||||
std::set<ElementsKind> candidates_;
|
||||
};
|
||||
|
||||
TNode<Number> JSGraphAssembler::ArrayBufferViewByteLength(
|
||||
TNode<JSArrayBufferView> array_buffer_view,
|
||||
TNode<JSArrayBufferView> array_buffer_view, InstanceType instance_type,
|
||||
std::set<ElementsKind> elements_kinds_candidates, TNode<Context> context) {
|
||||
ArrayBufferViewAccessBuilder builder(this,
|
||||
ArrayBufferViewAccessBuilder builder(this, instance_type,
|
||||
std::move(elements_kinds_candidates));
|
||||
return ExitMachineGraph<Number>(
|
||||
builder.BuildByteLength(array_buffer_view, context),
|
||||
@ -768,7 +778,8 @@ TNode<Number> JSGraphAssembler::ArrayBufferViewByteLength(
|
||||
TNode<Number> JSGraphAssembler::TypedArrayLength(
|
||||
TNode<JSTypedArray> typed_array,
|
||||
std::set<ElementsKind> elements_kinds_candidates, TNode<Context> context) {
|
||||
ArrayBufferViewAccessBuilder builder(this, elements_kinds_candidates);
|
||||
ArrayBufferViewAccessBuilder builder(this, JS_TYPED_ARRAY_TYPE,
|
||||
elements_kinds_candidates);
|
||||
return ExitMachineGraph<Number>(builder.BuildLength(typed_array, context),
|
||||
MachineType::PointerRepresentation(),
|
||||
TypeCache::Get()->kJSTypedArrayLengthType);
|
||||
|
@ -1034,7 +1034,7 @@ class V8_EXPORT_PRIVATE JSGraphAssembler : public GraphAssembler {
|
||||
// efficient code. Pass an empty {elements_kinds_candidates} to generate code
|
||||
// that is generic enough to handle all ElementsKinds.
|
||||
TNode<Number> ArrayBufferViewByteLength(
|
||||
TNode<JSArrayBufferView> array_buffer_view,
|
||||
TNode<JSArrayBufferView> array_buffer_view, InstanceType instance_type,
|
||||
std::set<ElementsKind> elements_kinds_candidates, TNode<Context> context);
|
||||
// Computes the length for a given {typed_array}. If the set of possible
|
||||
// ElementsKinds is known statically pass as {elements_kinds_candidates} to
|
||||
|
@ -7287,7 +7287,7 @@ Reduction JSCallReducer::ReduceArrayBufferViewByteLengthAccessor(
|
||||
TNode<JSTypedArray> typed_array =
|
||||
TNode<JSTypedArray>::UncheckedCast(receiver);
|
||||
TNode<Number> length = a.ArrayBufferViewByteLength(
|
||||
typed_array, std::move(elements_kinds), a.ContextInput());
|
||||
typed_array, instance_type, std::move(elements_kinds), a.ContextInput());
|
||||
|
||||
return ReplaceWithSubgraph(&a, length);
|
||||
}
|
||||
@ -7976,8 +7976,8 @@ Reduction JSCallReducer::ReduceDataViewAccess(Node* node, DataViewAccess access,
|
||||
} else {
|
||||
JSCallReducerAssembler a(this, node);
|
||||
byte_length = a.ArrayBufferViewByteLength(
|
||||
TNode<JSArrayBufferView>::UncheckedCast(receiver), {},
|
||||
a.ContextInput());
|
||||
TNode<JSArrayBufferView>::UncheckedCast(receiver), JS_DATA_VIEW_TYPE,
|
||||
{}, a.ContextInput());
|
||||
std::tie(effect, control) = ReleaseEffectAndControlFromAssembler(&a);
|
||||
}
|
||||
|
||||
|
19
test/mjsunit/regress/regress-1380398.js
Normal file
19
test/mjsunit/regress/regress-1380398.js
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2022 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 --turbofan --harmony-rab-gsab
|
||||
|
||||
function test() {
|
||||
const ab = new ArrayBuffer(2996, { maxByteLength: 8588995 });
|
||||
const dv = new DataView(ab);
|
||||
const len = dv.byteLength;
|
||||
return len >= 255;
|
||||
}
|
||||
|
||||
%PrepareFunctionForOptimization(test);
|
||||
assertTrue(test());
|
||||
assertTrue(test());
|
||||
%OptimizeFunctionOnNextCall(test);
|
||||
assertTrue(test());
|
||||
assertOptimized(test);
|
Loading…
Reference in New Issue
Block a user