Commit 611d84ee authored by Ana Peško's avatar Ana Peško Committed by Commit Bot

[regexp] Naive tier-up testing

This CL adds initial tests for the tier-up logic.

Change-Id: I6e6ff69604b14387e81b08d178f98d2227b4f496
Bug: v8:9566
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1776080
Commit-Queue: Ana Pesko <anapesko@google.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63503}
parent 2a75da33
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "src/logging/counters.h" #include "src/logging/counters.h"
#include "src/objects/heap-object-inl.h" #include "src/objects/heap-object-inl.h"
#include "src/objects/js-array-inl.h" #include "src/objects/js-array-inl.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/smi.h" #include "src/objects/smi.h"
#include "src/snapshot/natives.h" #include "src/snapshot/natives.h"
#include "src/trap-handler/trap-handler.h" #include "src/trap-handler/trap-handler.h"
...@@ -1047,6 +1048,24 @@ RUNTIME_FUNCTION(Runtime_SetWasmThreadsEnabled) { ...@@ -1047,6 +1048,24 @@ RUNTIME_FUNCTION(Runtime_SetWasmThreadsEnabled) {
return ReadOnlyRoots(isolate).undefined_value(); return ReadOnlyRoots(isolate).undefined_value();
} }
RUNTIME_FUNCTION(Runtime_RegexpHasBytecode) {
SealHandleScope shs(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
CONVERT_BOOLEAN_ARG_CHECKED(is_latin1, 1);
bool is_irregexp_bytecode = regexp.Bytecode(is_latin1).IsByteArray();
return isolate->heap()->ToBoolean(is_irregexp_bytecode);
}
RUNTIME_FUNCTION(Runtime_RegexpHasNativeCode) {
SealHandleScope shs(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
CONVERT_BOOLEAN_ARG_CHECKED(is_latin1, 1);
bool is_irregexp_native_code = regexp.Code(is_latin1).IsCode();
return isolate->heap()->ToBoolean(is_irregexp_native_code);
}
#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
RUNTIME_FUNCTION(Runtime_Has##Name) { \ RUNTIME_FUNCTION(Runtime_Has##Name) { \
CONVERT_ARG_CHECKED(JSObject, obj, 0); \ CONVERT_ARG_CHECKED(JSObject, obj, 0); \
......
...@@ -497,6 +497,8 @@ namespace internal { ...@@ -497,6 +497,8 @@ namespace internal {
F(IsThreadInWasm, 0, 1) \ F(IsThreadInWasm, 0, 1) \
F(IsWasmCode, 1, 1) \ F(IsWasmCode, 1, 1) \
F(IsWasmTrapHandlerEnabled, 0, 1) \ F(IsWasmTrapHandlerEnabled, 0, 1) \
F(RegexpHasBytecode, 2, 1) \
F(RegexpHasNativeCode, 2, 1) \
F(MapIteratorProtector, 0, 1) \ F(MapIteratorProtector, 0, 1) \
F(NeverOptimizeFunction, 1, 1) \ F(NeverOptimizeFunction, 1, 1) \
F(NotifyContextDisposed, 0, 1) \ F(NotifyContextDisposed, 0, 1) \
......
...@@ -395,6 +395,7 @@ ...@@ -395,6 +395,7 @@
'regress/regress-crbug-721835': [SKIP], 'regress/regress-crbug-721835': [SKIP],
'regress/regress-crbug-759327': [SKIP], 'regress/regress-crbug-759327': [SKIP],
'regress/regress-crbug-898974': [SKIP], 'regress/regress-crbug-898974': [SKIP],
'regexp-tier-up': [SKIP],
# These tests check that we can trace the compiler. # These tests check that we can trace the compiler.
'tools/compiler-trace-flags': [SKIP], 'tools/compiler-trace-flags': [SKIP],
...@@ -964,6 +965,9 @@ ...@@ -964,6 +965,9 @@
'ignition/regress-599001-verifyheap': [SKIP], 'ignition/regress-599001-verifyheap': [SKIP],
'unicode-test': [SKIP], 'unicode-test': [SKIP],
# The RegExp code cache means running this test multiple times is invalid.
'regexp-tier-up': [SKIP],
# Flaky crash on Odroid devices: https://crbug.com/v8/7678 # Flaky crash on Odroid devices: https://crbug.com/v8/7678
'regress/regress-336820': [PASS, ['arch == arm and not simulator_run', SKIP]], 'regress/regress-336820': [PASS, ['arch == arm and not simulator_run', SKIP]],
......
// 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 functional
// RegExp.prototype.replace.
// Flags: --regexp-tier-up --allow-natives-syntax --no-force-slow-path
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));
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