Skip to content

Commit b6234d6

Browse files
committed
unlinl the ILGenerator from the DynamicMethod #475
1 parent f167fe0 commit b6234d6

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

test/FastExpressionCompiler.Benchmarks/Issue468_Compile_vs_FastCompile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,6 @@ public object NoReuseILGenerator()
326326
[Benchmark]
327327
public object ReuseILGenerator()
328328
{
329-
return IssueTests.Issue475_Reuse_DynamicMethod_if_possible.TryPoolDynamicILGenerator();
329+
return IssueTests.Issue475_Reuse_DynamicMethod_if_possible.PoolDynamicILGenerator();
330330
}
331331
}

test/FastExpressionCompiler.IssueTests/Issue475_Reuse_DynamicMethod_if_possible.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ public void TryToReuseIlGenerator_for_any_signature(TestContext t)
189189
il.Emit(OpCodes.Ret);
190190

191191
var func = (Func<int, int>)dynMethod.CreateDelegate(typeof(Func<int, int>), ExpressionCompiler.EmptyArrayClosure);
192+
193+
// remove the link between DynamicMethod and ILGenerator, by setting it to null
194+
IlGeneratorField.SetValue(dynMethod, null);
195+
192196
t.AreEqual(41, func(41));
193197

194198
Type[] paramTypes = [typeof(ExpressionCompiler.ArrayClosure), typeof(int), typeof(int).MakeByRefType()];
@@ -244,7 +248,7 @@ public static object CreateDynamicILGenerator()
244248
return func;
245249
}
246250

247-
public static object TryPoolDynamicILGenerator()
251+
public static object PoolDynamicILGenerator()
248252
{
249253
var paramTypes = ExpressionCompiler.RentOrNewClosureTypeToParamTypes(typeof(int), typeof(int).MakeByRefType());
250254
var dynMethod = new DynamicMethod(string.Empty,
@@ -268,8 +272,11 @@ public static object TryPoolDynamicILGenerator()
268272
il.Emit(OpCodes.Ret);
269273

270274
var func = (Action2ndByRef<int>)dynMethod.CreateDelegate(typeof(Action2ndByRef<int>), ExpressionCompiler.EmptyArrayClosure);
275+
IlGeneratorField.SetValue(dynMethod, null); // required
276+
271277
Interlocked.Exchange(ref pooledILGenerator, il);
272278
ExpressionCompiler.FreeClosureTypeAndParamTypes(paramTypes);
279+
273280
return func;
274281
}
275282

@@ -294,7 +301,7 @@ internal static Action<DynamicMethod, ILGenerator, Type, Type[]> ReuseDynamicILG
294301
typeof(ExpressionCompiler.ArrayClosure),
295302
true);
296303

297-
var il = dynMethod.GetILGenerator();
304+
var il = dynMethod.GetILGenerator(256); // precalculating the size to avoid waste
298305

299306
var baseFields = DynamicILGeneratorType.BaseType.GetFields(allDeclared);
300307
foreach (var field in baseFields)
@@ -379,8 +386,8 @@ internal static Action<DynamicMethod, ILGenerator, Type, Type[]> ReuseDynamicILG
379386

380387
il.Emit(OpCodes.Ret);
381388

382-
return (Action<DynamicMethod, ILGenerator, Type, Type[]>)dynMethod.CreateDelegate(
383-
typeof(Action<DynamicMethod, ILGenerator, Type, Type[]>), ExpressionCompiler.EmptyArrayClosure);
389+
var act = dynMethod.CreateDelegate(typeof(Action<DynamicMethod, ILGenerator, Type, Type[]>), ExpressionCompiler.EmptyArrayClosure);
390+
return (Action<DynamicMethod, ILGenerator, Type, Type[]>)act;
384391
}
385392

386393
internal static Action<DynamicMethod, ILGenerator, Type, Type[]> ReuseDynamicILGeneratorOfAnySignature = ReuseDynamicILGeneratorOfAnyMethodSignature();

0 commit comments

Comments
 (0)