dotnet / corert

This repo contains CoreRT, an experimental .NET Core runtime optimized for AOT (ahead of time compilation) scenarios, with the accompanying compiler toolchain.
http://dot.net
MIT License
2.91k stars 508 forks source link

Question: Wasm sequence points #8285

Closed yowl closed 4 years ago

yowl commented 4 years ago

I'm trying to get source line debugging working again as it broke when we upgraded to LLVM 8 some time back.

With this IL:

// [S.P.Reflection.Core]System.Collections.Generic.EnumerableExtensions+<AsNothingButIEnumerable>d__0`1<T_System.__Canon>.MoveNext()
.method instance bool MoveNext() cil managed
{
  // Code size: 166
  .maxstack 2
  .locals init (bool V_0,
      int32 V_1)

  .try IL_0000 to IL_009C fault handler IL_009C to IL_00A4
  IL_0000:  ldarg.0
  IL_0001:  ldfld       int32 class System.Collections.Generic.EnumerableExtensions/<AsNothingButIEnumerable>d__0`1<class T_System.__Canon>::<>1__state
  IL_0006:  stloc.1
  IL_0007:  ldloc.1
  IL_0008:  brfalse.s   IL_0012
  IL_000A:  br.s        IL_000C
  IL_000C:  ldloc.1
  IL_000D:  ldc.i4.1
  IL_000E:  beq.s       IL_0014

Wasm is trying to test for a null on the ldfld at offset 1, and that's causing it to set up a landing pad and make a call to the EH iterator setup. The first sequence point for this method is at offset 36, so when its processing offset 1, there is no debug location set yet. This is problem for llvm as if the function has a debug location, and this one does (it gets set on offset 36), then any call that could be in-lined must have a debug location and this is a problem for the call to initialise the EH info enumerator.

One fix for this particular instance, and at least some of the others that are occurring, could be to not do the null check on the instance ldfld as this is an instance method, so unless this is a reflection call, then the instance should have been checked for null before calling the method.

Another option to fix this problem in general could be to just take the first sequence point and apply that to call to InitFromEhInfo. This is what I've done in the prolog if a call to a class constructor occurs. Would that be the right thing to do? Just asking in case I'm missing something better/obvious.

Thanks

jkotas commented 4 years ago

take the first sequence point and apply that to call to...

This is what RyuJIT does.

yowl commented 4 years ago

Thanks