Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Notice
This PR also changes the way classes bytecode is restore to the initially loaded into Lincheck agent. Instead of
redefineClasses(...)
nowretransformClasses(...)
is used in order to avoid double-instrumentation by other attached agents (e.g. intellij-coverage agent was throwingClassFormatError
because of this problem).Description
Relates to #254.
This PR adds a bytecode filter class, which "hides" bytecode generated by intellij-coverage agent (e.g. when using kover gradle plugin) from transformation that exist in Lincheck.
hits[index] = 1
)hits[index] += 1
)The bytecode tracking is implemented as state machine with 5 states (
+
symbol designates the direction of an arrow):Short overview:
HITS_INIT
andHITS_INIT_FIELD
states occur, when thehits
array (which stores coverage data) is loaded onto stack. The difference between state is the bytecode that they target: the 1st one occurs whenhits
was loaded viaLDC
instruction, the 2nd whenGETSTATIC
instruction was used.hits
usingLDC
is as follows:GETSTATIC
:GETSTATIC
is called twice, that is why on the diagram above there is a double-sided arrow betweenINITIAL
andLOADED_ON_STACK_STATIC
states (first timehits
is loaded on stack to check if it is null, then it is discarded, and lastly it is put on stack once again).HITS_IN_LOCAL
occurs when thehits
array is already saved to local variables of the method and the automata knows its index.ALOAD #n
instruction occurs automata goes intoHITS_BEFORE_ASSIGN
state, then it searches for bytecode ofhits[index] = 1
or/andhits[index] += 1
. When the assignment completed the state goes back toHITS_IN_LOCAL
.INITIAL
state again.