| // Copyright 2019 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. |
| |
| // Tier-up behavior differs between slow and fast paths in |
| // RegExp.prototype.replace with a function as an argument. |
| // Flags: --regexp-tier-up --regexp-tier-up-ticks=1 |
| // Flags: --allow-natives-syntax --no-force-slow-path --no-regexp-interpret-all |
| // Flags: --no-enable-experimental-regexp-engine |
| |
| const kLatin1 = true; |
| const kUnicode = false; |
| |
| function CheckRegexpNotYetCompiled(regexp) { |
| assertFalse(%RegexpHasBytecode(regexp, kLatin1) && |
| %RegexpHasNativeCode(regexp, kLatin1)); |
| assertFalse(%RegexpHasBytecode(regexp, kUnicode) && |
| %RegexpHasNativeCode(regexp, kUnicode)); |
| } |
| |
| // Testing RegExp.test method which calls into Runtime_RegExpExec. |
| let re = new RegExp('^.$'); |
| CheckRegexpNotYetCompiled(re); |
| |
| // Testing first execution of regexp with one-byte string subject. |
| re.test("a"); |
| assertTrue(%RegexpHasBytecode(re, kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re, kUnicode) && |
| !%RegexpHasNativeCode(re, kUnicode)); |
| // Testing second execution of regexp now with a two-byte string subject. |
| // This will compile to native code because we have a single tick counter |
| // for both string representations. |
| re.test("π"); |
| assertTrue(%RegexpHasBytecode(re, kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re, kUnicode) && |
| %RegexpHasNativeCode(re,kUnicode)); |
| // Testing tier-up when we're back to executing the regexp with a one byte |
| // string. |
| re.test("6"); |
| assertTrue(!%RegexpHasBytecode(re, kLatin1) && |
| %RegexpHasNativeCode(re,kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re, kUnicode) && |
| %RegexpHasNativeCode(re,kUnicode)); |
| re.test("7"); |
| assertTrue(!%RegexpHasBytecode(re, kLatin1) && |
| %RegexpHasNativeCode(re,kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re, kUnicode) && |
| %RegexpHasNativeCode(re,kUnicode)); |
| |
| // Testing String.replace method for non-global regexps. |
| var subject = "a11"; |
| re = /\w1/; |
| CheckRegexpNotYetCompiled(re); |
| |
| subject.replace(re, "x"); |
| assertTrue(%RegexpHasBytecode(re, kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re, kUnicode) && |
| !%RegexpHasNativeCode(re, kUnicode)); |
| subject.replace(re, "x"); |
| assertTrue(!%RegexpHasBytecode(re, kLatin1) && |
| %RegexpHasNativeCode(re, kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re, kUnicode) && |
| !%RegexpHasNativeCode(re, kUnicode)); |
| |
| // Testing String.replace method for global regexps. |
| let re_g = /\w111/g; |
| CheckRegexpNotYetCompiled(re_g); |
| // This regexp will not match, so it will only execute the bytecode once, |
| // without tiering-up and recompiling to native code. |
| subject.replace(re_g, "x"); |
| assertTrue(%RegexpHasBytecode(re_g, kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re_g, kUnicode) && |
| !%RegexpHasNativeCode(re_g, kUnicode)); |
| |
| // This regexp will match, so it will execute twice, and tier-up. |
| re_g = /\w1/g; |
| CheckRegexpNotYetCompiled(re_g); |
| subject.replace(re_g, "x"); |
| assertTrue(!%RegexpHasBytecode(re_g, kLatin1) && |
| %RegexpHasNativeCode(re_g, kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re_g, kUnicode) && |
| !%RegexpHasNativeCode(re_g, kUnicode)); |
| |
| // Testing String.replace method for global regexps with a function as a |
| // parameter. This will tier-up eagerly and compile to native code right |
| // away, even though the regexp is only executed once. |
| function f() { return "x"; } |
| re_g = /\w2/g; |
| CheckRegexpNotYetCompiled(re_g); |
| subject.replace(re_g, f); |
| assertTrue(!%RegexpHasBytecode(re_g, kLatin1) && |
| %RegexpHasNativeCode(re_g, kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re_g, kUnicode) && |
| !%RegexpHasNativeCode(re_g, kUnicode)); |
| |
| // Testing eager tier-up for very long strings. |
| let dna = "ATCG".repeat(251); |
| |
| re_g = />.*\n|\n/; |
| CheckRegexpNotYetCompiled(re_g); |
| |
| dna = dna.replace(re_g,""); |
| assertTrue(!%RegexpHasBytecode(re_g, kLatin1) && |
| %RegexpHasNativeCode(re_g, kLatin1)); |
| assertTrue(!%RegexpHasBytecode(re_g, kUnicode) && |
| !%RegexpHasNativeCode(re_g, kUnicode)); |