@@ -249,24 +249,14 @@ public unsafe void Process()
249249 var reportTypeGenericInstance = new GenericInstanceType ( coverageReporterTypeReference ) ;
250250 reportTypeGenericInstance . GenericArguments . Add ( moduleCoverageMetadataImplTypeDef ) ;
251251
252- var coverageProbeTypeDefinition = datadogTracerAssembly . MainModule . GetType ( typeof ( CoverageProbe ) . FullName ) ;
253- var coverageProbeTypeReference = module . ImportReference ( coverageProbeTypeDefinition ) ;
254- var reportAcquireCountersMethod = new MethodReference ( "AcquireFileCounter" , coverageProbeTypeReference , reportTypeGenericInstance )
252+ var reportGetCountersMethod = new MethodReference ( "GetFileCounter" , new PointerType ( module . TypeSystem . Void ) , reportTypeGenericInstance )
255253 {
256254 HasThis = false ,
257255 Parameters =
258256 {
259257 new ParameterDefinition ( module . TypeSystem . Int32 ) { Name = "fileIndex" }
260258 }
261259 } ;
262- var probePointerGetter = new MethodReference ( "get_Pointer" , new PointerType ( module . TypeSystem . Void ) , coverageProbeTypeReference )
263- {
264- HasThis = true
265- } ;
266- var probeDisposeMethod = new MethodReference ( nameof ( IDisposable . Dispose ) , module . TypeSystem . Void , coverageProbeTypeReference )
267- {
268- HasThis = true
269- } ;
270260
271261 // GenericInstanceMethod? arrayEmptyOfIntMethodReference = null;
272262 for ( var typeIndex = 0 ; typeIndex < moduleTypes . Count ; typeIndex ++ )
@@ -442,15 +432,6 @@ public unsafe void Process()
442432
443433 var methodBody = moduleTypeMethod . Body ;
444434 var instructions = methodBody . Instructions ;
445- if ( instructions . Any ( static instruction => instruction . OpCode == OpCodes . Tail ) )
446- {
447- // The invocation probe is released from an outer fault handler and a shared return
448- // epilogue. Wrapping a tail transfer in that protected region would invalidate its
449- // stack-constant semantics, so leave these uncommon methods untouched.
450- _logger . Debug ( $ "\t \t [NO] { moduleTypeMethod . FullName } , contains a tail call.") ;
451- continue ;
452- }
453-
454435 var instructionsOriginalLength = instructions . Count ;
455436 if ( instructions . Capacity < instructionsOriginalLength * 2 )
456437 {
@@ -474,22 +455,21 @@ public unsafe void Process()
474455 }
475456 }
476457
477- // The probe local owns the native buffer for the complete invocation. The generated
478- // outer fault handler and shared return epilogue release it on every exit path.
479- var probeVariable = new VariableDefinition ( coverageProbeTypeReference ) ;
480- VariableDefinition countersVariable ;
481- if ( _coverageMode == CoverageMode . LineExecution )
482- {
483- countersVariable = new VariableDefinition ( new PointerType ( module . TypeSystem . Byte ) ) ;
484- }
485- else
458+ VariableDefinition ? countersVariable = null ;
459+ if ( instructionsWithValidSequencePoints . Count > 1 || instructions [ 0 ] != instructionsWithValidSequencePoints [ 0 ] . Instruction )
486460 {
487- countersVariable = new VariableDefinition ( new PointerType ( module . TypeSystem . Int32 ) ) ;
488- }
461+ // Step 3 - Modify local var to add the Coverage counters instance.
462+ if ( _coverageMode == CoverageMode . LineExecution )
463+ {
464+ countersVariable = new VariableDefinition ( new PointerType ( module . TypeSystem . Byte ) ) ;
465+ }
466+ else
467+ {
468+ countersVariable = new VariableDefinition ( new PointerType ( module . TypeSystem . Int32 ) ) ;
469+ }
489470
490- methodBody . Variables . Add ( probeVariable ) ;
491- methodBody . Variables . Add ( countersVariable ) ;
492- methodBody . InitLocals = true ;
471+ methodBody . Variables . Add ( countersVariable ) ;
472+ }
493473
494474 // Step 4 - Insert the counter retriever
495475 FileMetadata fileMetadata ;
@@ -499,13 +479,12 @@ public unsafe void Process()
499479 fileDictionaryIndex [ filePath ] = fileMetadata ;
500480 }
501481
502- var probeProtectedStart = Instruction . Create ( OpCodes . Ldloca , probeVariable ) ;
503482 instructions . Insert ( 0 , Instruction . Create ( OpCodes . Ldc_I4 , fileMetadata . Index ) ) ;
504- instructions . Insert ( 1 , Instruction . Create ( OpCodes . Call , reportAcquireCountersMethod ) ) ;
505- instructions . Insert ( 2 , Instruction . Create ( OpCodes . Stloc , probeVariable ) ) ;
506- instructions . Insert ( 3 , probeProtectedStart ) ;
507- instructions . Insert ( 4 , Instruction . Create ( OpCodes . Call , probePointerGetter ) ) ;
508- instructions . Insert ( 5 , Instruction . Create ( OpCodes . Stloc , countersVariable ) ) ;
483+ instructions . Insert ( 1 , Instruction . Create ( OpCodes . Call , reportGetCountersMethod ) ) ;
484+ if ( countersVariable is not null )
485+ {
486+ instructions . Insert ( 2 , Instruction . Create ( OpCodes . Stloc , countersVariable ) ) ;
487+ }
509488
510489 // Step 5 - Insert line reporter
511490 for ( var i = 0 ; i < instructionsWithValidSequencePoints . Count ; i ++ )
@@ -656,7 +635,6 @@ public unsafe void Process()
656635 instructions . Insert ( ++ optIdx , currentInstructionClone ) ;
657636 }
658637
659- AddProbeCleanup ( methodBody , probeVariable , probeProtectedStart , probeDisposeMethod ) ;
660638 isDirty = true ;
661639 }
662640 }
@@ -977,77 +955,6 @@ private static void WriteInt32LittleEndian(byte[] buffer, int offset, int value)
977955 buffer [ offset + 3 ] = ( byte ) ( value >> 24 ) ;
978956 }
979957
980- private static void AddProbeCleanup (
981- Mono . Cecil . Cil . MethodBody methodBody ,
982- VariableDefinition probeVariable ,
983- Instruction protectedStart ,
984- MethodReference probeDisposeMethod )
985- {
986- var instructions = methodBody . Instructions ;
987- var returnInstructions = instructions . Where ( static instruction => instruction . OpCode == OpCodes . Ret ) . ToArray ( ) ;
988- VariableDefinition ? returnVariable = null ;
989- if ( returnInstructions . Length > 0 && methodBody . Method . ReturnType . MetadataType != MetadataType . Void )
990- {
991- returnVariable = new VariableDefinition ( methodBody . Method . ReturnType ) ;
992- methodBody . Variables . Add ( returnVariable ) ;
993- }
994-
995- var faultStart = Instruction . Create ( OpCodes . Ldloca , probeVariable ) ;
996- var faultDispose = Instruction . Create ( OpCodes . Call , probeDisposeMethod ) ;
997- var faultEnd = Instruction . Create ( OpCodes . Endfinally ) ;
998- var epilogueStart = returnInstructions . Length == 0 ? null : Instruction . Create ( OpCodes . Ldloca , probeVariable ) ;
999-
1000- foreach ( var exceptionHandler in methodBody . ExceptionHandlers )
1001- {
1002- // Cecil represents "until the end of the method" with null. The generated outer
1003- // fault handler extends the body, so existing regions must keep their original end.
1004- exceptionHandler . TryEnd ??= faultStart ;
1005- exceptionHandler . HandlerEnd ??= faultStart ;
1006- }
1007-
1008- if ( epilogueStart is not null )
1009- {
1010- foreach ( var returnInstruction in returnInstructions )
1011- {
1012- if ( returnVariable is not null )
1013- {
1014- returnInstruction . OpCode = OpCodes . Stloc ;
1015- returnInstruction . Operand = returnVariable ;
1016- instructions . Insert ( instructions . IndexOf ( returnInstruction ) + 1 , Instruction . Create ( OpCodes . Leave , epilogueStart ) ) ;
1017- }
1018- else
1019- {
1020- returnInstruction . OpCode = OpCodes . Leave ;
1021- returnInstruction . Operand = epilogueStart ;
1022- }
1023- }
1024- }
1025-
1026- instructions . Add ( faultStart ) ;
1027- instructions . Add ( faultDispose ) ;
1028- instructions . Add ( faultEnd ) ;
1029- if ( epilogueStart is not null )
1030- {
1031- instructions . Add ( epilogueStart ) ;
1032- instructions . Add ( Instruction . Create ( OpCodes . Call , probeDisposeMethod ) ) ;
1033- if ( returnVariable is not null )
1034- {
1035- instructions . Add ( Instruction . Create ( OpCodes . Ldloc , returnVariable ) ) ;
1036- }
1037-
1038- instructions . Add ( Instruction . Create ( OpCodes . Ret ) ) ;
1039- }
1040-
1041- methodBody . ExceptionHandlers . Add (
1042- new ExceptionHandler ( ExceptionHandlerType . Fault )
1043- {
1044- TryStart = protectedStart ,
1045- TryEnd = faultStart ,
1046- HandlerStart = faultStart ,
1047- HandlerEnd = epilogueStart ,
1048- } ) ;
1049- }
1050-
1051958 private static void RemoveShortOpCodes ( Instruction instruction )
1052959 {
1053960 if ( instruction . OpCode == OpCodes . Br_S ) { instruction . OpCode = OpCodes . Br ; }
0 commit comments