Commit 232bf1ff authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

Clamp properly in the String.p.indexOf reduction

This fixes a bug introduced in crrev.com/c/2660995.
String.prototype.indexOf must clamp the `position` argument as per
step:

  7. Let start be the result of clamping pos between 0 and len.

Source: tc39.es/ecma262/#sec-string.prototype.indexof

Previously, this was done in the StringIndexOf builtin, but the recent
refactor changed builtin implementations to match the spec more
closely (i.e. to clamp in String.prototype.indexOf, not
StringIndexOf). This means we now have to clamp in
JSCallReducer::ReduceStringPrototypeIndexOf.

Tbr: neis@chromium.org
Bug: chromium:1194869
Change-Id: I5af8d41b50f4905453f03079e3ee6d46186536db
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2799359Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73772}
parent 389eb1f8
...@@ -4905,6 +4905,14 @@ Reduction JSCallReducer::ReduceStringPrototypeIndexOf(Node* node) { ...@@ -4905,6 +4905,14 @@ Reduction JSCallReducer::ReduceStringPrototypeIndexOf(Node* node) {
Node* position = n.Argument(1); Node* position = n.Argument(1);
new_position = effect = graph()->NewNode( new_position = effect = graph()->NewNode(
simplified()->CheckSmi(p.feedback()), position, effect, control); simplified()->CheckSmi(p.feedback()), position, effect, control);
Node* receiver_length =
graph()->NewNode(simplified()->StringLength(), new_receiver);
new_position = graph()->NewNode(
simplified()->NumberMin(),
graph()->NewNode(simplified()->NumberMax(), new_position,
jsgraph()->ZeroConstant()),
receiver_length);
} }
NodeProperties::ReplaceEffectInput(node, effect); NodeProperties::ReplaceEffectInput(node, effect);
......
// Copyright 2021 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 --no-lazy-feedback-allocation
// Flags: --interrupt-budget=100
function f() {
return "".indexOf("", 2);
}
%PrepareFunctionForOptimization(f)
assertEquals(f(), 0);
assertEquals(f(), 0);
%OptimizeFunctionOnNextCall(f)
assertEquals(f(), 0);
assertEquals(f(), 0);
function g() {
return "".indexOf("", 2);
}
for (let i = 0; i < 191; i++) {
// Expect a natural optimization here due to low interrupt budget.
assertEquals(g(), 0);
}
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