@@ -519,27 +519,34 @@ private void InstrumentMethod(MethodDefinition method)
519519 InstrumentIL ( method ) ;
520520 }
521521
522+ /// <summary>
523+ /// The base idea is to inject an int placeholder for every sequence point. We register source+placeholder+lines(from sequence point) for final accounting.
524+ /// Instrumentation alg(current instruction: instruction we're analyzing):
525+ /// 1) We get all branches for the method
526+ /// 2) We get the sequence point of every instruction of method(start line/end line)
527+ /// 3) We check if current instruction is reachable and coverable
528+ /// 4) For every sequence point of an instruction we put load(int hint placeholder)+call opcode above current instruction
529+ /// 5) We patch all jump to current instruction with first injected instruction(load)
530+ /// 6) If current instruction is a target for a branch we inject again load(int hint placeholder)+call opcode above current instruction
531+ /// 7) We patch all jump to current instruction with first injected instruction(load)
532+ /// </summary>
522533 private void InstrumentIL ( MethodDefinition method )
523534 {
524535 method . Body . SimplifyMacros ( ) ;
525536 ILProcessor processor = method . Body . GetILProcessor ( ) ;
526-
527537 var index = 0 ;
528538 var count = processor . Body . Instructions . Count ;
529-
530539 var branchPoints = _cecilSymbolHelper . GetBranchPoints ( method ) ;
531-
532540 var unreachableRanges = _reachabilityHelper . FindUnreachableIL ( processor . Body . Instructions , processor . Body . ExceptionHandlers ) ;
533541 var currentUnreachableRangeIx = 0 ;
534-
535542 for ( int n = 0 ; n < count ; n ++ )
536543 {
537- var instruction = processor . Body . Instructions [ index ] ;
538- var sequencePoint = method . DebugInformation . GetSequencePoint ( instruction ) ;
539- var targetedBranchPoints = branchPoints . Where ( p => p . EndOffset == instruction . Offset ) ;
544+ var currentInstruction = processor . Body . Instructions [ index ] ;
545+ var sequencePoint = method . DebugInformation . GetSequencePoint ( currentInstruction ) ;
546+ var targetedBranchPoints = branchPoints . Where ( p => p . EndOffset == currentInstruction . Offset ) ;
540547
541548 // make sure we're looking at the correct unreachable range (if any)
542- var instrOffset = instruction . Offset ;
549+ var instrOffset = currentInstruction . Offset ;
543550 while ( currentUnreachableRangeIx < unreachableRanges . Length && instrOffset > unreachableRanges [ currentUnreachableRangeIx ] . EndOffset )
544551 {
545552 currentUnreachableRangeIx ++ ;
@@ -554,26 +561,26 @@ private void InstrumentIL(MethodDefinition method)
554561 }
555562
556563 // Check is both reachable, _and_ coverable
557- if ( isUnreachable || _cecilSymbolHelper . SkipNotCoverableInstruction ( method , instruction ) )
564+ if ( isUnreachable || _cecilSymbolHelper . SkipNotCoverableInstruction ( method , currentInstruction ) )
558565 {
559566 index ++ ;
560567 continue ;
561568 }
562569
563570 if ( sequencePoint != null && ! sequencePoint . IsHidden )
564571 {
565- if ( _cecilSymbolHelper . SkipInlineAssignedAutoProperty ( _parameters . SkipAutoProps , method , instruction ) )
572+ if ( _cecilSymbolHelper . SkipInlineAssignedAutoProperty ( _parameters . SkipAutoProps , method , currentInstruction ) )
566573 {
567574 index ++ ;
568575 continue ;
569576 }
570577
571- var target = AddInstrumentationCode ( method , processor , instruction , sequencePoint ) ;
572- foreach ( var _instruction in processor . Body . Instructions )
573- ReplaceInstructionTarget ( _instruction , instruction , target ) ;
578+ var firstInjectedInstrumentedOpCode = AddInstrumentationCode ( method , processor , currentInstruction , sequencePoint ) ;
579+ foreach ( var bodyInstruction in processor . Body . Instructions )
580+ ReplaceInstructionTarget ( bodyInstruction , currentInstruction , firstInjectedInstrumentedOpCode ) ;
574581
575582 foreach ( ExceptionHandler handler in processor . Body . ExceptionHandlers )
576- ReplaceExceptionHandlerBoundary ( handler , instruction , target ) ;
583+ ReplaceExceptionHandlerBoundary ( handler , currentInstruction , firstInjectedInstrumentedOpCode ) ;
577584
578585 index += 2 ;
579586 }
@@ -589,12 +596,12 @@ private void InstrumentIL(MethodDefinition method)
589596 if ( branchTarget . StartLine == - 1 || branchTarget . Document == null )
590597 continue ;
591598
592- var target = AddInstrumentationCode ( method , processor , instruction , branchTarget ) ;
593- foreach ( var _instruction in processor . Body . Instructions )
594- ReplaceInstructionTarget ( _instruction , instruction , target ) ;
599+ var firstInjectedInstrumentedOpCode = AddInstrumentationCode ( method , processor , currentInstruction , branchTarget ) ;
600+ foreach ( var bodyInstruction in processor . Body . Instructions )
601+ ReplaceInstructionTarget ( bodyInstruction , currentInstruction , firstInjectedInstrumentedOpCode ) ;
595602
596603 foreach ( ExceptionHandler handler in processor . Body . ExceptionHandlers )
597- ReplaceExceptionHandlerBoundary ( handler , instruction , target ) ;
604+ ReplaceExceptionHandlerBoundary ( handler , currentInstruction , firstInjectedInstrumentedOpCode ) ;
598605
599606 index += 2 ;
600607 }
@@ -704,20 +711,20 @@ private Instruction AddInstrumentationInstructions(MethodDefinition method, ILPr
704711
705712 private static void ReplaceInstructionTarget ( Instruction instruction , Instruction oldTarget , Instruction newTarget )
706713 {
707- if ( instruction . Operand is Instruction _instruction )
714+ if ( instruction . Operand is Instruction operandInstruction )
708715 {
709- if ( _instruction == oldTarget )
716+ if ( operandInstruction == oldTarget )
710717 {
711718 instruction . Operand = newTarget ;
712719 return ;
713720 }
714721 }
715- else if ( instruction . Operand is Instruction [ ] _instructions )
722+ else if ( instruction . Operand is Instruction [ ] operandInstructions )
716723 {
717- for ( int i = 0 ; i < _instructions . Length ; i ++ )
724+ for ( int i = 0 ; i < operandInstructions . Length ; i ++ )
718725 {
719- if ( _instructions [ i ] == oldTarget )
720- _instructions [ i ] = newTarget ;
726+ if ( operandInstructions [ i ] == oldTarget )
727+ operandInstructions [ i ] = newTarget ;
721728 }
722729 }
723730 }
0 commit comments