v8/test/mjsunit/code-coverage-class-fields.js
Jakob Gruber 3002ff44ee [coverage] Add dedicated FunctionLiteral counters
Prior to this CL, call counts at function scope were taken from the
FeedbackVector::invocation_count field. This had two major drawbacks:
1. for generator functions, these count the number of resumptions
instead of the number of calls; and 2. the invocation count is not
maintained in optimized code.

The solution implemented here is to add a dedicated call counter at
function scope which is incremented exactly once each time the
function is called.

A minor complication is that our coverage output format expects
function-scope counts in the dedicated CoverageFunction object, and
not as a CoverageBlock. Thus function-scope block counts are initially
marked with magic positions, and later recognized and rewritten during
processing.

This CL thus fixes reported generator function call counts and enables
optimizations in block coverage modes (more to come in a follow-up).

Drive-by: Don't report functions with empty source ranges.

Bug: v8:6000,v8:9148,v8:9212
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng
Change-Id: Idbe5edb35a595cf12b6649314738ac00efd173b8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1613996
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61574}
2019-05-16 12:43:33 +00:00

175 lines
4.9 KiB
JavaScript

// Copyright 2017 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 --no-always-opt --harmony-public-fields
// Flags: --harmony-static-fields --no-stress-flush-bytecode
// Files: test/mjsunit/code-coverage-utils.js
%DebugToggleBlockCoverage(true);
TestCoverage(
"class with no fields",
`
class X { // 000
}; // 050
`,
[{"start":0,"end":99,"count":1}]
);
TestCoverage(
"class that's not created",
`
class X { // 000
x = function() { } // 050
}; // 100
`,
[{"start":0,"end":149,"count":1},
{"start":52,"end":70,"count":0}]
);
TestCoverage(
"class with field thats not called",
`
class X { // 000
x = function() { } // 050
}; // 100
let x = new X(); // 150
`,
[{"start":0,"end":199,"count":1},
{"start":52,"end":70,"count":1},
{"start":56,"end":70,"count":0}]
);
TestCoverage(
"class field",
`
class X { // 000
x = function() { } // 050
}; // 100
let x = new X(); // 150
x.x(); // 200
`,
[{"start":0,"end":249,"count":1},
{"start":52,"end":70,"count":1},
{"start":56,"end":70,"count":1}]
);
TestCoverage(
"non contiguous class field",
`
class X { // 000
x = function() { } // 050
foo() { } // 100
y = function() {} // 150
}; // 200
let x = new X(); // 250
x.x(); // 300
x.y(); // 350
`,
[{"start":0,"end":399,"count":1},
{"start":52,"end":169,"count":1},
{"start":56,"end":70,"count":1},
{"start":102,"end":111,"count":0},
{"start":156,"end":169,"count":1}]
);
TestCoverage(
"non contiguous class field thats called",
`
class X { // 000
x = function() { } // 050
foo() { } // 100
y = function() {} // 150
}; // 200
let x = new X(); // 250
x.x(); // 300
x.y(); // 350
x.foo(); // 400
`,
[{"start":0,"end":449,"count":1},
{"start":52,"end":169,"count":1},
{"start":56,"end":70,"count":1},
{"start":102,"end":111,"count":1},
{"start":156,"end":169,"count":1}]
);
TestCoverage(
"class with initializer iife",
`
class X { // 000
x = (function() { })() // 050
}; // 100
let x = new X(); // 150
`,
[{"start":0,"end":199,"count":1},
{"start":52,"end":74,"count":1},
{"start":57,"end":71,"count":1}]
);
TestCoverage(
"class with computed field",
`
function f() {}; // 000
class X { // 050
[f()] = (function() { })() // 100
}; // 150
let x = new X(); // 200
`,
[{"start":0,"end":249,"count":1},
{"start":0,"end":15,"count":1},
{"start":102,"end":128,"count":1},
{"start":111,"end":125,"count":1}]
);
TestCoverage(
"static class field that's not called",
`
class X { // 000
static x = function() { } // 050
}; // 100
`,
[{"start":0,"end":149,"count":1},
{"start":52,"end":77,"count":1},
{"start":63,"end":77,"count":0}]
);
TestCoverage(
"static class field",
`
class X { // 000
static x = function() { } // 050
}; // 100
X.x(); // 150
`,
[{"start":0,"end":199,"count":1},
{"start":52,"end":77,"count":1},
{"start":63,"end":77,"count":1}]
);
TestCoverage(
"static class field with iife",
`
class X { // 000
static x = (function() { })() // 050
}; // 100
`,
[{"start":0,"end":149,"count":1},
{"start":52,"end":81,"count":1},
{"start":64,"end":78,"count":1}]
);
TestCoverage(
"computed static class field",
`
function f() {} // 000
class X { // 050
static [f()] = (function() { })() // 100
}; // 150
`,
[{"start":0,"end":199,"count":1},
{"start":0,"end":15,"count":1},
{"start":102,"end":135,"count":1},
{"start":118,"end":132,"count":1}]
);