6181ce59fc
This fast path works for ASCII-only strings and is similar to the existing fast-path in C++. Important differences: - The locale check is done at Turbofan optimization time instead of at runtime - Use tables of size 256 instead of 128 to save a bounds-check when handling one-byte strings. - It first performs an equality check that's optimized for detecting inequality quickly by comparing the strings from both ends. If the equality check succeeds, we are done. Otherwise chances are high that the strings differ according to collation level L1 already. Therefore, we first do an L1 check and perform the L3 check only when L1 didn't find a difference. This is based on the assumption that few strings are identical except for different capitalization. - Use the Torque version of string flattening instead of the runtime version. Bug: v8:12196 Change-Id: I2d043c1138846783f6d567b736d34063ba9301e5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3268465 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/main@{#77946}
59 lines
2.4 KiB
JavaScript
59 lines
2.4 KiB
JavaScript
// 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: --opt --allow-natives-syntax --interrupt-budget=1024
|
|
|
|
function check() {
|
|
// Equal prefix.
|
|
assertTrue("asdf".localeCompare("asdf") == 0);
|
|
assertTrue("asd".localeCompare("asdf") < 0);
|
|
assertTrue("asdff".localeCompare("asdf") > 0);
|
|
|
|
// Completely Ignorable.
|
|
// TODO (jgruber): This case is currently wrong in the C++ fast-path.
|
|
// assertEquals("asdf".localeCompare("asdf\01"), 0);
|
|
assertEquals("asdf".localeCompare("as\01df"), 0);
|
|
assertEquals("asdf".localeCompare("\01asdf"), 0);
|
|
|
|
// Chars differ.
|
|
assertTrue("asdf".localeCompare("asdq") < 0);
|
|
assertTrue("asdq".localeCompare("asdf") > 0);
|
|
|
|
// Interesting locales.
|
|
assertEquals('ö'.localeCompare('oe', 'de'), -1);
|
|
assertEquals('Ö'.localeCompare('oe', 'de'), -1);
|
|
assertEquals('ö'.localeCompare('o', 'de-u-co-phonebk'), 1);
|
|
assertEquals('ö'.localeCompare('p', 'de-u-co-phonebk'), -1);
|
|
assertEquals('Ö'.localeCompare('o', 'de-u-co-phonebk'), 1);
|
|
assertEquals('Ö'.localeCompare('p', 'de-u-co-phonebk'), -1);
|
|
assertEquals('ö'.localeCompare('o\u0308', 'de-u-co-phonebk'), 0);
|
|
assertEquals('ö'.localeCompare('O\u0308', 'de-u-co-phonebk'), -1);
|
|
assertEquals('Ö'.localeCompare('o\u0308', 'de-u-co-phonebk'), 1);
|
|
assertEquals('Ö'.localeCompare('O\u0308', 'de-u-co-phonebk'), 0);
|
|
|
|
assertEquals('ch'.localeCompare('ca', 'cs-CZ'), 1);
|
|
assertEquals('AA'.localeCompare('A-A', 'th'), 0);
|
|
|
|
// Attempt to hit different cases of the localeCompare fast path.
|
|
assertEquals('aAaaaö'.localeCompare('aaaaaö', 'en-US'), 1);
|
|
assertEquals('aaaaaöA'.localeCompare('aaaaaöa', 'en-US'), 1);
|
|
assertEquals('ab\u0308'.localeCompare('aa\u0308', 'en-US'), 1);
|
|
assertEquals('aA'.localeCompare('aaa', 'en-US'), -1);
|
|
assertEquals('aa'.localeCompare('aAa', 'en-US'), -1);
|
|
assertEquals('aA'.localeCompare('aa', 'en-US'), 1);
|
|
assertEquals('aa'.localeCompare('aA', 'en-US'), -1);
|
|
}
|
|
|
|
// TODO(tebbi): Make isOptimized() from mjsunit.js available in intl tests.
|
|
function isOptimized(fun) {
|
|
return (%GetOptimizationStatus(fun) & (1 << 4)) != 0;
|
|
}
|
|
|
|
assertFalse(isOptimized(check));
|
|
while (true) {
|
|
var optimized = isOptimized(check);
|
|
check();
|
|
if (optimized) break;
|
|
}
|