Profiling Partially Executed Lines

Applies to AQTime 8.81, last modified on January 18, 2022

The following sections briefly describe the concept of partially executed lines and how AQTime counts them during the profiling.

About Partially Executed Lines

Some source code lines are compiled into several blocks of binary code; typical examples are branch statements like if...then or switch...case. You can see the total number of blocks that constitute a source code line in the Block Count column of the Details panel. Since the code coverage is performed on the compiled code, these lines are considered completely executed only if all of the corresponding compiled code blocks were executed. If not all of the blocks were covered during the profiling, these lines are reported as partially executed.

For example, consider the following Delphi code:

if (a < b) or (c > d) then DoSomething;

This line can be split into three blocks:

  1. The a < b condition.
  2. The c > d condition.
  3. A call to DoSomething.

Now suppose that the a < b expression evaluates to True and thus triggers the DoSomething routine call. The resulting coverage for the source code line depends on whether the code uses short-circuit or long-circuit expression evaluation. By default, the Delphi compiler generates code for short-circuit expression evaluation, so the c > d expression is not evaluated and that is why the line will be reported as partially executed. But if the code is generated with long-circuit (complete) evaluation, the c > d expression is forced to be evaluated and in this case the line is fully covered.

Another example of an operation which is split by the compiler into several blocks and which is quite frequent is Delphi’s div operation that performs integer division. The Delphi compiler breaks this instruction into several blocks when the divisor is a power of 2.

Note that for lines that constitute several blocks in the compiled code, the Hit Count value indicates the total hit count for all blocks corresponding to the line. For example, consider the following C++ code with a switch statement:

C++

switch (Param)
{
  case 1:
     DoActionA();
     break;
  case 2:
     DoActionB();
     break;
  case 3:
     DoActionC();
     break;
}

The compiler would typically generate four blocks for the switch (Param) line which are equivalent to the following code:

C++

if (Param == 1) goto label1;
if (Param == 2) goto label2;
if (Param == 3) goto label3;
goto label4;

Suppose this code is initially executed with the Param value of 1. In this case, only the first branch is executed so that the hit count for the switch (Param) line becomes 1. If the same code is then executed with the Param value of 3, the three branch blocks are hit one after another and therefore the hit count is incremented by 3. This way the resulting hit count for the switch (Param) line is 4 (rather than 2 as one would expect) as this is the number of hits for compiled code blocks corresponding to that line. You can see that in the image below.

How AQTime Counts Partially Executed Lines

The Coverage profiler includes the Mark partially executed lines as option that specifies how AQTime counts partially executed lines when it calculates the Lines Covered, Lines Uncovered and % Covered values and how AQTime marks such lines (with a red, green or yellow dot) in the Lines page of the Details panel and in the Editor (see Viewing Profiling Results in the Source Code). This option can have one of the three following values:

Value Description
Partially executed AQTime marks partially executed lines with yellow dots and counts them as unexecuted when calculating the Lines Covered and Lines Uncovered columns.
Completely executed AQTime marks partially executed lines with green dots and counts them as executed.
Non-executed AQTime marks partially executed lines with red dots and counts them as unexecuted.

See Also

Coverage Profiler Results
Report Panel
Explorer Panel
Details Panel
Analyzing Profiler Results

Highlight search results