Skip to content

Dependency Injection using ILEmit is generating additional MSIL nop operations in the DynamicMethod #59624

Closed

Description

@allantargino

Description

When inspecting MSIL code generated by Dependency Injection dynamic compilation using ILEmit, everytime there is a ldloca.s instruction, 3 nop operations are also generated.

Configuration

  • Which version of .NET is the code running on? .NET Framework 4.62
  • What OS and version, and what distro if applicable? Windows 11 (22000.194)
  • What is the architecture (x64, x86, ARM, ARM64)? x64

Other information

To reproduce the issue, compile Microsoft.Extensions.DependencyInjection using SAVE_ASSEMBLIES symbol. Then run ServiceProviderILEmitContainerTests.ScopedServiceCanBeResolved and inspect MSIL code in artifacts\bin\Microsoft.Extensions.DependencyInjection.Tests\net462-*\Test*.dll

  [...]
  IL_0047: ldloc.2      // sync
  IL_0048: ldloca.s     lockTaken
  IL_004a: nop
  IL_004b: nop
  IL_004c: nop
  IL_004d: call         void [mscorlib]System.Threading.Monitor::Enter(object, bool&)

  IL_0052: ldloc.1      // resolvedServices
  IL_0053: ldloc.0      // key
  IL_0054: ldloca.s     service
  IL_0056: nop
  IL_0057: nop
  IL_0058: nop
  IL_0059: callvirt     instance bool class [mscorlib]System.Collections.Generic.IDictionary`2<valuetype [Microsoft.Extensions.DependencyInjection]Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, object>::TryGetValue(!0/*valuetype [Microsoft.Extensions.DependencyInjection]Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey*/, !1/*object*/&)
  IL_005e: brtrue       IL_007c
  [...]

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Sep 26, 2021
  2. allantargino commented on Sep 26, 2021

    @allantargino
    ContributorAuthor

    The ldloca.s instruction expects an 1 byte argument (byte), while we are providing a 4 bytes argument (lockTakenLocal.LocalIndex and resultLocal.LocalIndex are int).

    context.Generator.Emit(OpCodes.Ldloca_S, lockTakenLocal.LocalIndex);
    // Monitor.Enter
    context.Generator.Emit(OpCodes.Call, ServiceLookupHelpers.MonitorEnterMethodInfo);
    // Load resolved services
    Ldloc(context.Generator, resolvedServicesLocal.LocalIndex);
    // Load cache key
    Ldloc(context.Generator, cacheKeyLocal.LocalIndex);
    // Load address of result local
    context.Generator.Emit(OpCodes.Ldloca_S, resultLocal.LocalIndex);

    As per documentation, in the remarks section:

    If the opcode parameter requires an argument, the caller must ensure that the argument length matches the length of the declared parameter. Otherwise, results will be unpredictable. For example, if the Emit instruction requires a 2-byte operand and the caller supplies a 4-byte operand, the runtime will emit two additional bytes to the instruction stream. These extra bytes will be Nop instructions.

  3. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 26, 2021
  4. added this to the Future milestone on Sep 27, 2021
  5. removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 27, 2021
  6. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 27, 2021
  7. added a commit that references this issue on Sep 27, 2021
    766874e
  8. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 27, 2021
  9. added a commit that references this issue on Sep 28, 2021
    77bd789
  10. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 28, 2021
  11. ghost locked as resolved and limited conversation to collaborators on Nov 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions