6dc35ab46f
This adds support to the KeyedLoadIC to ignore out of bounds accesses for Strings and return undefined instead. We add a dedicated bit to the Smi handler to encode the OOB state and have TurboFan generate appropriate code for that case as well. This is mostly useful when programs accidentially access past the length of a string, which was observed and fixed for example in Babel recently, see https://github.com/babel/babel/pull/6589 for details. The idea is to also extend this mechanism to Arrays and maybe other receivers, as reading beyond the length is also often used in jQuery and other popular libraries. Note that this is considered a mitigation for a performance cliff and not a general optimization of OOB accesses. These should still be avoided and handled properly instead. This seems to further improve the babel test on the web-tooling-benchmark by around 1%, because the OOB access no longer turns the otherwise MONOMORPHIC access into MEGAMORPHIC state. Bug: v8:6936, v8:7014 Change-Id: I9df03304e056d7001a65da8e9621119f8e9bb55b Reviewed-on: https://chromium-review.googlesource.com/744022 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#49049}
31 lines
796 B
JavaScript
31 lines
796 B
JavaScript
// Copyright 2017 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 --no-always-opt
|
|
|
|
function foo(s) {
|
|
return s[5];
|
|
}
|
|
|
|
assertEquals("f", foo("abcdef"));
|
|
assertEquals(undefined, foo("a"));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals("f", foo("abcdef"));
|
|
assertEquals(undefined, foo("a"));
|
|
assertOptimized(foo);
|
|
|
|
// Now mess with the String.prototype.
|
|
String.prototype.__proto__ = new Proxy(String.prototype.__proto__, {
|
|
get(target, property) {
|
|
return "5";
|
|
}
|
|
});
|
|
|
|
assertEquals("f", foo("abcdef"));
|
|
assertEquals("5", foo("a"));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals("f", foo("abcdef"));
|
|
assertEquals("5", foo("a"));
|
|
assertOptimized(foo);
|