coverage.js 9.81 KB
Newer Older
1 2 3 4
// 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.

5
// Flags: --allow-natives-syntax --no-always-turbofan --turbofan
6
// Flags: --no-stress-flush-code
7
// Flags: --no-stress-incremental-marking
8
// Flags: --no-concurrent-recompilation
9
// Flags: --no-baseline-batch-compilation
10
// Flags: --no-maglev
11

12 13 14 15 16 17
var source =
`
function fib(x) {
  if (x < 2) return 1;
  return fib(x-1) + fib(x-2);
}
18 19 20
function is_optimized(f) {
  return (%GetOptimizationStatus(f) & 16) ? "optimized" : "unoptimized";
}
21 22 23 24 25 26
(function iife() {
  return 1;
})();
fib(5);
`;

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
var break_source =
`
function g() {
  debugger;
}
function f(x) {
  if (x == 0) g();
  else f(x - 1);
}
function h() {
  g();
}
f(3);
`;

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
var nested =
`
var f = (function outer() {
  function nested_0() {
    return function nested_1() {
      return function nested_2() {
        return function nested_3() {}
      }
    }
  }
  function nested_4() {}
  return nested_0();
})();
f()()();
`;

58
let {session, contextGroup, Protocol} = InspectorTest.start("Test collecting code coverage data with Profiler.collectCoverage.");
59 60

function ClearAndGC() {
61 62
  return Protocol.Runtime.evaluate({ expression: "fib = g = f = h = is_optimized = null;" })
             .then(GC);
63 64 65
}

function GC() {
66
  return Protocol.HeapProfiler.collectGarbage();
67 68
}

69 70 71 72 73
function LogSorted(message) {
  message.result.result.sort((a, b) => parseInt(a.scriptId) - parseInt(b.scriptId));
  return InspectorTest.logMessage(message);
}

74
InspectorTest.runTestSuite([
75
  function testPreciseCountBaseline(next)
76 77
  {
    Protocol.Runtime.enable()
78
      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
79 80 81
      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
      .then(GC)
      .then(Protocol.Profiler.enable)
82
      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
83 84 85 86 87 88 89
      .then(Protocol.Profiler.takePreciseCoverage)
      .then(LogSorted)
      .then(Protocol.Profiler.takePreciseCoverage)
      .then(LogSorted)
      .then(Protocol.Profiler.stopPreciseCoverage)
      .then(Protocol.Profiler.disable)
      .then(Protocol.Runtime.disable)
90
      .then(ClearAndGC)
91 92
      .then(next);
  },
93
  function testPreciseCountCoverage(next)
94 95
  {
    Protocol.Runtime.enable()
96
      .then(Protocol.Profiler.enable)
97
      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
98
      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
99
      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
100
      .then(InspectorTest.logMessage)
101
      .then(ClearAndGC)
102
      .then(Protocol.Profiler.takePreciseCoverage)
103
      .then(LogSorted)
104
      .then(Protocol.Profiler.takePreciseCoverage)
105
      .then(LogSorted)
106 107
      .then(Protocol.Profiler.stopPreciseCoverage)
      .then(Protocol.Profiler.disable)
108
      .then(Protocol.Runtime.disable)
109
      .then(ClearAndGC)
110 111 112 113 114
      .then(next);
  },
  function testPreciseCoverageFail(next)
  {
    Protocol.Runtime.enable()
115
      .then(Protocol.Profiler.enable)
116
      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
117 118 119
      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
      .then(InspectorTest.logMessage)
      .then(ClearAndGC)
120
      .then(Protocol.Profiler.takePreciseCoverage)
121
      .then(InspectorTest.logMessage)
122
      .then(Protocol.Profiler.disable)
123
      .then(Protocol.Runtime.disable)
124
      .then(ClearAndGC)
125 126 127 128 129
      .then(next);
  },
  function testBestEffortCoverage(next)
  {
    Protocol.Runtime.enable()
130
      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
131 132 133
      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
      .then(InspectorTest.logMessage)
      .then(ClearAndGC)
134
      .then(Protocol.Profiler.getBestEffortCoverage)
135
      .then(LogSorted)
136
      .then(Protocol.Profiler.getBestEffortCoverage)
137
      .then(LogSorted)
138
      .then(Protocol.Runtime.disable)
139
      .then(ClearAndGC)
140 141
      .then(next);
  },
142 143 144 145
  function testBestEffortCoverageWithPreciseBinaryEnabled(next)
  {
    Protocol.Runtime.enable()
    .then(Protocol.Profiler.enable)
146
    .then(() => Protocol.Profiler.startPreciseCoverage({detailed: false}))
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
    .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
    .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
    .then(InspectorTest.logMessage)
    .then(ClearAndGC)
    .then(Protocol.Profiler.getBestEffortCoverage)
    .then(LogSorted)
    .then(Protocol.Profiler.getBestEffortCoverage)
    .then(LogSorted)
    .then(ClearAndGC)
    .then(Protocol.Profiler.stopPreciseCoverage)
    .then(Protocol.Profiler.disable)
    .then(Protocol.Runtime.disable)
    .then(ClearAndGC)
    .then(next);
  },
  function testBestEffortCoverageWithPreciseCountEnabled(next)
163 164
  {
    Protocol.Runtime.enable()
165
      .then(Protocol.Profiler.enable)
166
      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
167
      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
168 169 170
      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
      .then(InspectorTest.logMessage)
      .then(ClearAndGC)
171
      .then(Protocol.Profiler.getBestEffortCoverage)
172
      .then(LogSorted)
173
      .then(Protocol.Profiler.getBestEffortCoverage)
174
      .then(LogSorted)
175
      .then(ClearAndGC)
176 177
      .then(Protocol.Profiler.stopPreciseCoverage)
      .then(Protocol.Profiler.disable)
178
      .then(Protocol.Runtime.disable)
179
      .then(ClearAndGC)
180 181
      .then(next);
  },
182
  function testEnablePreciseCountCoverageAtPause(next)
183 184 185
  {
    function handleDebuggerPause() {
      Protocol.Profiler.enable()
186
          .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
187 188 189 190 191
          .then(Protocol.Debugger.resume)
    }
    Protocol.Debugger.enable();
    Protocol.Debugger.oncePaused().then(handleDebuggerPause);
    Protocol.Runtime.enable()
192
      .then(() => Protocol.Runtime.compileScript({ expression: break_source, sourceURL: arguments.callee.name, persistScript: true }))
193 194 195 196 197
      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
      .then(InspectorTest.logMessage)
      .then(ClearAndGC)
      .then(Protocol.Profiler.takePreciseCoverage)
      .then(LogSorted)
198
      .then(ClearAndGC)
199 200 201
      .then(Protocol.Profiler.stopPreciseCoverage)
      .then(Protocol.Profiler.disable)
      .then(Protocol.Runtime.disable)
202 203 204 205 206 207 208 209
      .then(Protocol.Debugger.disable)
      .then(ClearAndGC)
      .then(next);
  },
  function testPreciseBinaryCoverage(next)
  {
    Protocol.Runtime.enable()
      .then(Protocol.Profiler.enable)
210
      .then(() => Protocol.Profiler.startPreciseCoverage({detailed: false}))
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
      .then(InspectorTest.logMessage)
      .then(Protocol.Profiler.takePreciseCoverage)
      .then(LogSorted)
      .then(() => Protocol.Runtime.evaluate({ expression: "is_optimized(fib)" }))
      .then(message => InspectorTest.logMessage(message))
      .then(() => Protocol.Runtime.evaluate({ expression: "fib(20)" }))
      .then(message => InspectorTest.logMessage(message))
      .then(() => Protocol.Runtime.evaluate({ expression: "is_optimized(fib)" }))
      .then(message => InspectorTest.logMessage(message))
      .then(Protocol.Profiler.takePreciseCoverage)
      .then(LogSorted)
      .then(Protocol.Profiler.stopPreciseCoverage)
      .then(Protocol.Profiler.disable)
      .then(Protocol.Runtime.disable)
      .then(ClearAndGC)
228 229
      .then(next);
  },
230 231 232 233
  function testPreciseEmptyScriptCoverageEntries(next)
  {
    // Enabling the debugger holds onto script objects even though its
    // functions can be garbage collected. We would get empty ScriptCoverage
234
    // entries unless we remove them.
235 236 237 238 239 240
    Protocol.Debugger.enable()
      .then(Protocol.Runtime.enable)
      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
      .then(ClearAndGC)
      .then(Protocol.Profiler.enable)
241
      .then(() => Protocol.Profiler.startPreciseCoverage({detailed: false}))
242 243 244 245 246 247 248 249 250 251 252 253 254
      .then(Protocol.Profiler.takePreciseCoverage)
      .then(LogSorted)
      .then(Protocol.Profiler.stopPreciseCoverage)
      .then(Protocol.Profiler.disable)
      .then(Protocol.Runtime.disable)
      .then(Protocol.Debugger.disable)
      .then(ClearAndGC)
      .then(next);
  },
  function testPreciseCountCoveragePartial(next)
  {
    Protocol.Runtime.enable()
      .then(Protocol.Profiler.enable)
255
      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
256 257 258 259 260 261 262 263 264 265 266 267 268 269
      .then(() => Protocol.Runtime.compileScript({ expression: nested, sourceURL: arguments.callee.name, persistScript: true }))
      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
      .then(InspectorTest.logMessage)
      .then(Protocol.Profiler.takePreciseCoverage)
      .then(LogSorted)
      .then(() => Protocol.Runtime.evaluate({ expression: "f()" }))
      .then(Protocol.Profiler.takePreciseCoverage)
      .then(LogSorted)
      .then(Protocol.Profiler.stopPreciseCoverage)
      .then(Protocol.Profiler.disable)
      .then(Protocol.Runtime.disable)
      .then(ClearAndGC)
      .then(next);
  },
270
]);