From 0188a33c786c1e170435b41a9892590f3757f58e Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Tue, 28 Apr 2020 14:40:22 +0200 Subject: [PATCH] [turbofan] Fix bug in typed array iteration ... by making sure we deopt when the buffer is detached. Bug: chromium:1074736 Change-Id: I86e4e63014767766d7c079c3a3e38d947c76ef10 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2168874 Commit-Queue: Georg Neis Commit-Queue: Michael Stanton Auto-Submit: Georg Neis Reviewed-by: Michael Stanton Cr-Commit-Position: refs/heads/master@{#67437} --- src/compiler/js-call-reducer.cc | 26 ++++++++++++++++++++++++ test/mjsunit/compiler/regress-1074736.js | 17 ++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 test/mjsunit/compiler/regress-1074736.js diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc index 40782afa44..845cc2df2e 100644 --- a/src/compiler/js-call-reducer.cc +++ b/src/compiler/js-call-reducer.cc @@ -5506,6 +5506,32 @@ Reduction JSCallReducer::ReduceArrayIterator(Node* node, return NoChange(); } + if (array_kind == ArrayIteratorKind::kTypedArray) { + // Make sure we deopt when the JSArrayBuffer is detached. + if (!dependencies()->DependOnArrayBufferDetachingProtector()) { + CallParameters const& p = CallParametersOf(node->op()); + if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) { + return NoChange(); + } + Node* buffer = effect = graph()->NewNode( + simplified()->LoadField(AccessBuilder::ForJSArrayBufferViewBuffer()), + receiver, effect, control); + 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::WasDetachedBit::kMask)), + jsgraph()->ZeroConstant()); + effect = graph()->NewNode( + simplified()->CheckIf(DeoptimizeReason::kArrayBufferWasDetached, + p.feedback()), + check, effect, control); + } + } + // Morph the {node} into a JSCreateArrayIterator with the given {kind}. RelaxControls(node); node->ReplaceInput(0, receiver); diff --git a/test/mjsunit/compiler/regress-1074736.js b/test/mjsunit/compiler/regress-1074736.js new file mode 100644 index 0000000000..6395026454 --- /dev/null +++ b/test/mjsunit/compiler/regress-1074736.js @@ -0,0 +1,17 @@ +// Copyright 2020 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 + +var arr = new Uint8Array(); +%ArrayBufferDetach(arr.buffer); + +function foo() { + return arr[Symbol.iterator](); +} + +%PrepareFunctionForOptimization(foo); +assertThrows(foo, TypeError); +%OptimizeFunctionOnNextCall(foo); +assertThrows(foo, TypeError);