v8/test/mjsunit/regress/cross-script-vars.js
Mythri A b086cb7b9a Check that function was prepared before optimizing using manually
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}
2019-07-11 14:57:49 +00:00

575 lines
15 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
function PrintDesc(desc, s) {
var json;
if (desc) {
json = JSON.stringify(desc);
} else {
json = "<no such property>";
}
if (s === undefined) {
print(json);
} else {
print(s + ": " + json);
}
}
var counters;
var test_realm;
var cfg;
function GetDescriptor() {
var code = 'Object.getOwnPropertyDescriptor(global, "x")';
var desc = Realm.eval(test_realm, code);
// PrintDesc(desc);
return desc;
}
function SetUp() {
counters = {};
Realm.shared = {counters: counters};
test_realm = Realm.create();
Realm.eval(test_realm, 'var global = Realm.global(Realm.current());');
print("=====================");
print("Test realm: " + test_realm);
assertEquals(undefined, GetDescriptor());
}
function TearDown() {
Realm.dispose(test_realm);
print("OK");
}
function AddStrict(code, cfg) {
return cfg.strict ? '"use strict"; ' + code : code;
}
function ForceMutablePropertyCellType() {
Realm.eval(test_realm, 'global.x = {}; global.x = undefined;');
}
function DeclareVar() {
var code = 'var x;';
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function DefineVar(v) {
var code = 'var x = ' + v;
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function DefineLoadVar() {
var name = 'LoadVar_' + test_realm;
var code =
'var x;' +
'function ' + name + '() {' +
' return x;' +
'};'
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function LoadVar() {
var name = 'LoadVar_' + test_realm;
var code = (cfg.optimize ? '%PrepareFunctionForOptimization(' + name + ');' : '') +
(cfg.optimize ? '%OptimizeFunctionOnNextCall(' + name + ');' : '') +
name + '();';
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function DefineStoreVar() {
var name = 'StoreVar_' + test_realm;
var code = 'var g = (Function("return this"))();' +
'var x;' +
'function ' + name + '(v) {' +
' return x = v;' +
'};';
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function StoreVar(v) {
var name = 'StoreVar_' + test_realm;
var code = (cfg.optimize ? '%PrepareFunctionForOptimization(' + name + ');' : '') +
(cfg.optimize ? '%OptimizeFunctionOnNextCall(' + name + ');' : '') +
name + '(' + v + ');';
return Realm.eval(test_realm, AddStrict(code, cfg));
}
// It does 13 iterations which results in 27 loads
// and 14 stores.
function LoadStoreLoop() {
var code = 'for(var x = 0; x < 13; x++);';
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function DefineRWDataProperty() {
var code =
'Object.defineProperty(global, "x", { ' +
' value: 42, ' +
' writable: true, ' +
' enumerable: true, ' +
' configurable: true ' +
'});';
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function DefineRODataProperty() {
var code =
'Object.defineProperty(global, "x", { ' +
' value: 42, ' +
' writable: false, ' +
' enumerable: true, ' +
' configurable: true ' +
'});';
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function SetX_(v) {
var code =
'global.x_ = ' + v + '; ';
return Realm.eval(test_realm, code);
}
function DefineRWAccessorProperty() {
var code =
'Object.defineProperty(global, "x", {' +
' get: function() { Realm.shared.counters.get_count++; return this.x_; },' +
' set: function(v) { Realm.shared.counters.set_count++; this.x_ = v; },' +
' enumerable: true, configurable: true' +
'});';
counters.get_count = 0;
counters.set_count = 0;
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function DefineROAccessorProperty() {
var code =
'Object.defineProperty(global, "x", {' +
' get: function() { Realm.shared.counters.get_count++; return this.x_; },' +
' enumerable: true, configurable: true' +
'});';
counters.get_count = 0;
counters.set_count = 0;
return Realm.eval(test_realm, AddStrict(code, cfg));
}
function testSuite(opt_cfg) {
//
// Non strict.
//
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: false};
DeclareVar();
DefineLoadVar();
DefineStoreVar();
assertEquals(undefined, LoadVar());
assertEquals(false, GetDescriptor().configurable);
// Force property cell type to kMutable.
DefineVar(undefined);
DefineVar(153);
assertEquals(false, GetDescriptor().configurable);
assertEquals(153, LoadVar());
assertEquals(113, StoreVar(113));
assertEquals(113, LoadVar());
LoadStoreLoop();
assertEquals(13, LoadVar());
TearDown();
})();
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: false};
ForceMutablePropertyCellType();
DefineLoadVar();
DefineStoreVar();
DefineRWDataProperty();
assertEquals(42, LoadVar());
assertEquals(true, GetDescriptor().configurable);
DefineVar(153);
assertEquals(true, GetDescriptor().configurable);
assertEquals(153, LoadVar());
assertEquals(113, StoreVar(113));
assertEquals(113, LoadVar());
LoadStoreLoop();
assertEquals(13, LoadVar());
// Now reconfigure to accessor.
DefineRWAccessorProperty();
assertEquals(undefined, GetDescriptor().value);
assertEquals(true, GetDescriptor().configurable);
assertEquals(0, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(undefined, LoadVar());
assertEquals(1, counters.get_count);
assertEquals(0, counters.set_count);
LoadStoreLoop();
assertEquals(28, counters.get_count);
assertEquals(14, counters.set_count);
assertEquals(13, LoadVar());
assertEquals(29, counters.get_count);
assertEquals(14, counters.set_count);
TearDown();
})();
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: false};
ForceMutablePropertyCellType();
DefineLoadVar();
DefineStoreVar();
DefineRODataProperty();
assertEquals(42, LoadVar());
assertEquals(true, GetDescriptor().configurable);
DefineVar(153);
assertEquals(42, LoadVar());
assertEquals(113, StoreVar(113));
assertEquals(42, LoadVar());
LoadStoreLoop();
assertEquals(42, LoadVar());
// Now reconfigure to accessor property.
DefineRWAccessorProperty();
assertEquals(undefined, GetDescriptor().value);
assertEquals(true, GetDescriptor().configurable);
assertEquals(0, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(undefined, LoadVar());
assertEquals(1, counters.get_count);
assertEquals(0, counters.set_count);
LoadStoreLoop();
assertEquals(28, counters.get_count);
assertEquals(14, counters.set_count);
assertEquals(13, LoadVar());
assertEquals(29, counters.get_count);
assertEquals(14, counters.set_count);
TearDown();
})();
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: false};
ForceMutablePropertyCellType();
DefineLoadVar();
DefineStoreVar();
DefineRWAccessorProperty();
assertEquals(0, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(true, GetDescriptor().configurable);
assertEquals(undefined, LoadVar());
assertEquals(1, counters.get_count);
assertEquals(0, counters.set_count);
DefineVar(153);
assertEquals(true, GetDescriptor().configurable);
assertEquals(1, counters.get_count);
assertEquals(1, counters.set_count);
assertEquals(153, LoadVar());
assertEquals(2, counters.get_count);
assertEquals(1, counters.set_count);
assertEquals(113, StoreVar(113));
assertEquals(2, counters.get_count);
assertEquals(2, counters.set_count);
assertEquals(113, LoadVar());
assertEquals(3, counters.get_count);
assertEquals(2, counters.set_count);
LoadStoreLoop();
assertEquals(30, counters.get_count);
assertEquals(16, counters.set_count);
assertEquals(13, LoadVar());
assertEquals(31, counters.get_count);
assertEquals(16, counters.set_count);
// Now reconfigure to data property.
DefineRWDataProperty();
assertEquals(42, GetDescriptor().value);
assertEquals(42, LoadVar());
assertEquals(113, StoreVar(113));
assertEquals(31, counters.get_count);
assertEquals(16, counters.set_count);
TearDown();
})();
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: false};
ForceMutablePropertyCellType();
DefineLoadVar();
DefineStoreVar();
DefineROAccessorProperty();
assertEquals(0, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(true, GetDescriptor().configurable);
assertEquals(undefined, LoadVar());
assertEquals(1, counters.get_count);
assertEquals(0, counters.set_count);
SetX_(42);
assertEquals(42, LoadVar());
assertEquals(2, counters.get_count);
assertEquals(0, counters.set_count);
DefineVar(153);
assertEquals(true, GetDescriptor().configurable);
assertEquals(2, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(42, LoadVar());
assertEquals(3, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(113, StoreVar(113));
assertEquals(3, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(42, LoadVar());
assertEquals(4, counters.get_count);
assertEquals(0, counters.set_count);
LoadStoreLoop();
assertEquals(5, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(42, LoadVar());
assertEquals(6, counters.get_count);
assertEquals(0, counters.set_count);
// Now reconfigure to data property.
DefineRWDataProperty();
assertEquals(42, GetDescriptor().value);
assertEquals(42, LoadVar());
assertEquals(113, StoreVar(113));
assertEquals(6, counters.get_count);
assertEquals(0, counters.set_count);
TearDown();
})();
//
// Strict.
//
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: true};
DeclareVar();
DefineLoadVar();
DefineStoreVar();
assertEquals(undefined, LoadVar());
assertEquals(false, GetDescriptor().configurable);
// Force property cell type to kMutable.
DefineVar(undefined);
DefineVar(153);
assertEquals(false, GetDescriptor().configurable);
assertEquals(153, LoadVar());
assertEquals(113, StoreVar(113));
assertEquals(113, LoadVar());
LoadStoreLoop();
assertEquals(13, LoadVar());
TearDown();
})();
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: true};
ForceMutablePropertyCellType();
DefineLoadVar();
DefineStoreVar();
DefineRWDataProperty();
assertEquals(42, LoadVar());
assertEquals(true, GetDescriptor().configurable);
DefineVar(153);
assertEquals(true, GetDescriptor().configurable);
assertEquals(153, LoadVar());
assertEquals(113, StoreVar(113));
assertEquals(113, LoadVar());
LoadStoreLoop();
assertEquals(13, LoadVar());
TearDown();
})();
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: true};
ForceMutablePropertyCellType();
DefineLoadVar();
DefineStoreVar();
DefineRWDataProperty();
assertEquals(true, GetDescriptor().configurable);
assertEquals(true, GetDescriptor().writable);
assertEquals(113, StoreVar(113));
DefineRODataProperty();
assertEquals(true, GetDescriptor().configurable);
assertEquals(false, GetDescriptor().writable);
assertEquals(42, LoadVar());
assertEquals(true, GetDescriptor().configurable);
assertThrows('DefineVar(153)');
assertEquals(42, LoadVar());
assertThrows('StoreVar(113)');
assertThrows('StoreVar(113)');
assertEquals(42, LoadVar());
assertThrows('StoreVar(42)');
assertEquals(42, LoadVar());
assertThrows('LoadStoreLoop()');
assertEquals(42, LoadVar());
TearDown();
})();
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: true};
ForceMutablePropertyCellType();
DefineLoadVar();
DefineStoreVar();
DefineRWAccessorProperty();
assertEquals(0, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(true, GetDescriptor().configurable);
assertEquals(undefined, LoadVar());
assertEquals(1, counters.get_count);
assertEquals(0, counters.set_count);
DefineVar(153);
assertEquals(true, GetDescriptor().configurable);
assertEquals(1, counters.get_count);
assertEquals(1, counters.set_count);
assertEquals(153, LoadVar());
assertEquals(2, counters.get_count);
assertEquals(1, counters.set_count);
assertEquals(113, StoreVar(113));
assertEquals(2, counters.get_count);
assertEquals(2, counters.set_count);
assertEquals(113, LoadVar());
assertEquals(3, counters.get_count);
assertEquals(2, counters.set_count);
LoadStoreLoop();
assertEquals(30, counters.get_count);
assertEquals(16, counters.set_count);
assertEquals(13, LoadVar());
assertEquals(31, counters.get_count);
assertEquals(16, counters.set_count);
// Now reconfigure to data property.
DefineRWDataProperty();
assertEquals(42, GetDescriptor().value);
assertEquals(42, LoadVar());
assertEquals(113, StoreVar(113));
assertEquals(31, counters.get_count);
assertEquals(16, counters.set_count);
TearDown();
})();
(function() {
SetUp();
cfg = {optimize: opt_cfg.optimize, strict: true};
ForceMutablePropertyCellType();
DefineLoadVar();
DefineStoreVar();
DefineROAccessorProperty();
assertEquals(0, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(true, GetDescriptor().configurable);
assertEquals(undefined, LoadVar());
assertEquals(1, counters.get_count);
assertEquals(0, counters.set_count);
SetX_(42);
assertEquals(42, LoadVar());
assertEquals(2, counters.get_count);
assertEquals(0, counters.set_count);
assertThrows('DefineVar(153)');
assertEquals(true, GetDescriptor().configurable);
assertEquals(2, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(42, LoadVar());
assertEquals(3, counters.get_count);
assertEquals(0, counters.set_count);
assertThrows('StoreVar(113)');
assertEquals(3, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(42, LoadVar());
assertEquals(4, counters.get_count);
assertEquals(0, counters.set_count);
assertThrows('LoadStoreLoop()');
assertEquals(4, counters.get_count);
assertEquals(0, counters.set_count);
assertEquals(42, LoadVar());
assertEquals(5, counters.get_count);
assertEquals(0, counters.set_count);
// Now reconfigure to data property.
DefineRWDataProperty();
assertEquals(42, GetDescriptor().value);
assertEquals(42, LoadVar());
assertEquals(113, StoreVar(113));
assertEquals(5, counters.get_count);
assertEquals(0, counters.set_count);
TearDown();
})();
} // testSuite
testSuite({optimize: false});
testSuite({optimize: true});