0714bd9fa0
This is a reland of eccf186749
Original change's description:
> [interpreter] Separate bytecodes for one-shot property loads and stores
>
> Create LdaNamedPropertyNoFeedback and StaNamedPropertyNoFeedback
> for one-shot property loads and stores. This CL replaces the runtime
> calls with new bytecodes for named property load stores in one-shot code.
> the runtime calls needed extra set of consecutive registers and
> additional move instructions. This increased the size of
> bytecode-array and possibly extended the life time of objects.
> By replacing them with NoFeedback bytecodes we avoid these issues.
>
> Bug: v8:8072
> Change-Id: I20a38a5ce9940026171d870d354787fe0b7c5a6f
> Reviewed-on: https://chromium-review.googlesource.com/1196725
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Georg Neis <neis@chromium.org>
> Commit-Queue: Chandan Reddy <chandanreddy@google.com>
> Cr-Commit-Position: refs/heads/master@{#56211}
Bug: v8:8072
Change-Id: Ie8e52b37daf35c7bc08bb910d7b15a9b783354e4
Reviewed-on: https://chromium-review.googlesource.com/1245742
Commit-Queue: Chandan Reddy <chandanreddy@google.com>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56266}
202 lines
4.0 KiB
JavaScript
202 lines
4.0 KiB
JavaScript
// Copyright 2018 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.
|
|
|
|
Debug = debug.Debug;
|
|
|
|
// StaCurrentContextSlot
|
|
success(10, `(function(){
|
|
const x = 10;
|
|
function f1() {return x;}
|
|
return x;
|
|
})()`);
|
|
|
|
// StaNamedProperty
|
|
var a = {name: 'foo'};
|
|
function set_name(a) {
|
|
a.name = 'bar';
|
|
return a.name;
|
|
}
|
|
|
|
fail(`set_name(a)`);
|
|
success('bar', `set_name({name: 'foo'})`);
|
|
|
|
// StaNamedOwnProperty
|
|
var name_value = 'value';
|
|
function create_object_literal() {
|
|
var obj = {name: name_value};
|
|
return obj.name;
|
|
};
|
|
|
|
success('value', `create_object_literal()`);
|
|
|
|
// StaKeyedProperty
|
|
var arrayValue = 1;
|
|
function create_array_literal() {
|
|
return [arrayValue];
|
|
}
|
|
var b = { 1: 2 };
|
|
|
|
success([arrayValue], `create_array_literal()`)
|
|
fail(`b[1] ^= 2`);
|
|
|
|
// StaInArrayLiteral
|
|
function return_array_use_spread(a) {
|
|
return [...a];
|
|
}
|
|
|
|
success([1], `return_array_use_spread([1])`);
|
|
|
|
// CallAccessorSetter
|
|
var array = [1,2,3];
|
|
fail(`array.length = 2`);
|
|
success(2, `[1,2,3].length = 2`);
|
|
|
|
// StaDataPropertyInLiteral
|
|
function return_literal_with_data_property(a) {
|
|
return {[a] : 1};
|
|
}
|
|
|
|
success({foo: 1}, `return_literal_with_data_property('foo')`);
|
|
|
|
// Set builtins with temporary objects
|
|
var set = new Set([1,2]);
|
|
fail(`set.add(3).size`);
|
|
success(1, `new Set().add(1).size`);
|
|
|
|
success(0, `(() => { const s = new Set([1]); s.delete(1); return s.size; })()`);
|
|
fail(`set.delete(1)`);
|
|
|
|
success(0, `(() => { const s = new Set([1]); s.clear(); return s.size; })()`);
|
|
fail(`set.clear()`);
|
|
|
|
// new set
|
|
success(3, `(() => {
|
|
let s = 0;
|
|
for (const a of new Set([1,2]))
|
|
s += a;
|
|
return s;
|
|
})()`);
|
|
// existing set
|
|
success(3, `(() => {
|
|
let s = 0;
|
|
for (const a of set)
|
|
s += a;
|
|
return s;
|
|
})()`);
|
|
// existing iterator
|
|
var setIterator = set.entries();
|
|
fail(`(() => {
|
|
let s = 0;
|
|
for (const a of setIterator)
|
|
s += a;
|
|
return s;
|
|
})()`);
|
|
|
|
// Array builtins with temporary objects
|
|
success([1,1,1], '[1,2,3].fill(1)');
|
|
fail(`array.fill(1)`);
|
|
|
|
success([1], `(() => { const a = []; a.push(1); return a; })()`);
|
|
fail(`array.push(1)`);
|
|
|
|
success([1], `(() => { const a = [1,2]; a.pop(); return a; })()`);
|
|
fail(`array.pop()`);
|
|
|
|
success([3,2,1], `[1,2,3].reverse()`);
|
|
fail(`array.reverse()`);
|
|
|
|
success([1,2,3], `[2,1,3].sort()`);
|
|
fail(`array.sort()`);
|
|
|
|
success([2,3], `[1,2,3].splice(1,2)`);
|
|
fail(`array.splice(1,2)`);
|
|
|
|
success([1,2], `(() => { const a = [2]; a.unshift(1); return a; })()`);
|
|
fail(`array.unshift(1)`);
|
|
success(1, `[1,2].shift()`);
|
|
fail(`array.shift()`);
|
|
|
|
// new array
|
|
success(6, `(() => {
|
|
let s = 0;
|
|
for (const a of [1,2,3])
|
|
s += a;
|
|
return s;
|
|
})()`);
|
|
// existing array
|
|
success(6, `(() => {
|
|
let s = 0;
|
|
for (const a of array)
|
|
s += a;
|
|
return s;
|
|
})()`);
|
|
// existing iterator
|
|
var arrayIterator = array.entries();
|
|
fail(`(() => {
|
|
let s = 0;
|
|
for (const a of arrayIterator)
|
|
s += a;
|
|
return s;
|
|
})()`);
|
|
|
|
success(6, `array.reduce((a,b) => a + b, 0)`);
|
|
|
|
// Map builtins with temporary objects
|
|
var map = new Map([[1,2]]);
|
|
fail(`map.set(3, 4).size`);
|
|
success(1, `new Map().set(1, 2).size`);
|
|
|
|
success(0, `(() => {
|
|
const m = new Map([[1, 2]]);
|
|
m.delete(1);
|
|
return m.size;
|
|
})()`);
|
|
fail(`map.delete(1)`);
|
|
|
|
success(0, `(() => {
|
|
const m = new Map([[1, 2]]);
|
|
m.clear();
|
|
return m.size;
|
|
})()`);
|
|
fail(`map.clear()`);
|
|
|
|
// new set
|
|
success(2, `(() => {
|
|
let s = 0;
|
|
for (const [a, b] of new Map([[1,2]]))
|
|
s += b;
|
|
return s;
|
|
})()`);
|
|
// existing set
|
|
success(2, `(() => {
|
|
let s = 0;
|
|
for (const [a,b] of map)
|
|
s += b;
|
|
return s;
|
|
})()`);
|
|
// existing iterator
|
|
var mapIterator = map.entries();
|
|
fail(`(() => {
|
|
let s = 0;
|
|
for (const [a,b] of mapIterator)
|
|
s += a;
|
|
return s;
|
|
})()`);
|
|
|
|
// Regexps
|
|
var regExp = /a/;
|
|
success(true, `/a/.test('a')`);
|
|
fail(`/a/.test({toString: () => {map.clear(); return 'a';}})`)
|
|
fail(`regExp.test('a')`);
|
|
|
|
function success(expectation, source) {
|
|
const result = Debug.evaluateGlobal(source, true).value();
|
|
if (expectation !== undefined) assertEquals(expectation, result);
|
|
}
|
|
|
|
function fail(source) {
|
|
assertThrows(() => Debug.evaluateGlobal(source, true),
|
|
EvalError);
|
|
}
|