b086cb7b9a
With lazy feedback allocation and bytecode flushing we need to call %PrepareFunctionForOptimize before we call %OptimizeFunctionOnNextCall/ %OptimizeOsr. This cl: 1. Adds an additional state in pending optimized table to check if the optimization was triggered manually. 2. Changes the compilation pipeline to delete the entry from pending optimized table only if the optimization was triggered through %OptimizeFunctionOnNextCall / %OptimizeOsr. 3. Adds a check to enforce %PrepareFunctionForOptimize was called. 4. Adds a new run-time flag to only check in the d8 test runner. We don't want this check enabled in other cases like clusterfuzz that doesn't ensure %PrepareFunctionForOptimize is called. Bug: v8:8394, v8:8801, v8:9183 Change-Id: I9ae2b2da812e313c746b6df0b2da864c2ed5de51 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1664810 Commit-Queue: Mythri Alle <mythria@chromium.org> Reviewed-by: Michael Achenbach <machenbach@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#62653}
139 lines
2.9 KiB
JavaScript
139 lines
2.9 KiB
JavaScript
// Copyright 2015 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 --use-osr
|
|
|
|
"use strict";
|
|
|
|
function nest(body, name, depth) {
|
|
var header = "";
|
|
for (var i = 0; i < depth; i++) {
|
|
var x = "x" + (i + 1);
|
|
header += " for(var " + x + " = 0; " + x + " < 2; " + x + " = " + x + " + 1 | 0) {\n";
|
|
body = body + "}"
|
|
}
|
|
|
|
// Replace function name
|
|
var new_func = body.replace(new RegExp("function " + name + "\\(\\) {"),
|
|
"function " + name + "_" + x + "() {\n" + header);
|
|
|
|
// Replace PrepareForOptimize
|
|
return new_func.replace(new RegExp("%PrepareFunctionForOptimization\\(" + name + "\\);"),
|
|
"%PrepareFunctionForOptimization(" + name + "_" + x + ");");
|
|
}
|
|
|
|
function test(expected, func, depth) {
|
|
%PrepareFunctionForOptimization(func);
|
|
assertEquals(expected, func());
|
|
%PrepareFunctionForOptimization(func);
|
|
assertEquals(expected, func());
|
|
%PrepareFunctionForOptimization(func);
|
|
assertEquals(expected, func());
|
|
|
|
var orig = func.toString();
|
|
var name = func.name;
|
|
for (var depth = 1; depth < 4; depth++) {
|
|
var body = nest(orig, name, depth);
|
|
func = eval("(" + body + ")");
|
|
|
|
%PrepareFunctionForOptimization(func);
|
|
assertEquals(expected, func());
|
|
%PrepareFunctionForOptimization(func);
|
|
assertEquals(expected, func());
|
|
%PrepareFunctionForOptimization(func);
|
|
assertEquals(expected, func());
|
|
}
|
|
}
|
|
|
|
function foo() {
|
|
var result;
|
|
{
|
|
let sum = 0;
|
|
for (var i = 0; i < 10; i++) {
|
|
%OptimizeOsr();
|
|
sum += i;
|
|
%PrepareFunctionForOptimization(foo);
|
|
}
|
|
result = sum;
|
|
}
|
|
return result;
|
|
}
|
|
%PrepareFunctionForOptimization(foo);
|
|
|
|
test(45, foo);
|
|
|
|
function bar() {
|
|
let sum = 0;
|
|
for (var i = 0; i < 10; i++) {
|
|
%OptimizeOsr();
|
|
sum += i;
|
|
%PrepareFunctionForOptimization(bar);
|
|
}
|
|
return sum;
|
|
}
|
|
%PrepareFunctionForOptimization(bar);
|
|
|
|
test(45, bar);
|
|
|
|
function bon() {
|
|
{
|
|
let sum = 0;
|
|
for (var i = 0; i < 10; i++) {
|
|
if (i == 5) %OptimizeOsr();
|
|
sum += i;
|
|
}
|
|
return sum;
|
|
}
|
|
}
|
|
%PrepareFunctionForOptimization(bon);
|
|
|
|
test(45, bon);
|
|
|
|
function row() {
|
|
var i = 0;
|
|
{
|
|
let sum = 0;
|
|
while (true) {
|
|
if (i == 8) return sum;
|
|
%OptimizeOsr();
|
|
sum = i;
|
|
i = i + 1 | 0;
|
|
%PrepareFunctionForOptimization(row);
|
|
}
|
|
}
|
|
return 11;
|
|
}
|
|
%PrepareFunctionForOptimization(row);
|
|
|
|
test(7, row);
|
|
|
|
function nub() {
|
|
let i = 0;
|
|
while (i < 2) {
|
|
%OptimizeOsr();
|
|
i++;
|
|
%PrepareFunctionForOptimization(nub);
|
|
}
|
|
return i;
|
|
}
|
|
%PrepareFunctionForOptimization(nub);
|
|
|
|
test(2, nub);
|
|
|
|
function kub() {
|
|
var result = 0;
|
|
let i = 0;
|
|
while (i < 2) {
|
|
let x = i;
|
|
%OptimizeOsr();
|
|
i++;
|
|
result = x;
|
|
%PrepareFunctionForOptimization(kub);
|
|
}
|
|
return result;
|
|
}
|
|
%PrepareFunctionForOptimization(kub);
|
|
|
|
test(1, kub);
|