| // 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)); |