our_ICorJitInfo.getBuiltinClass(CLASSID_FIELD_HANDLE);
our_ICorJitInfo.getBuiltinClass(CLASSID_METHOD_HANDLE);
our_ICorJitInfo.getBuiltinClass(CLASSID_STRING);
- our_ICorJitInfo.getBuiltinClass(CLASSID_ARGUMENT_HANDLE);
our_ICorJitInfo.getBuiltinClass(CLASSID_RUNTIME_TYPE);
#ifdef fatMC
private IntPtr ObjectToHandle(Object obj)
{
+ // SuperPMI relies on the handle returned from this function being stable for the lifetime of the crossgen2 process
+ // If handle deletion is implemented, please update SuperPMI
IntPtr handle;
if (!_objectToHandle.TryGetValue(obj, out handle))
{
{
using (PerfEventSource.StartStopEvents.JitEvents())
{
- ParallelOptions options = new ParallelOptions
- {
- MaxDegreeOfParallelism = _parallelism
- };
- Parallel.ForEach(obj, options, dependency =>
+ Action<DependencyNodeCore<NodeFactory>> compileOneMethod = (DependencyNodeCore<NodeFactory> dependency) =>
{
MethodWithGCInfo methodCodeNodeNeedingCode = dependency as MethodWithGCInfo;
MethodDesc method = methodCodeNodeNeedingCode.Method;
{
using (PerfEventSource.StartStopEvents.JitMethodEvents())
{
+ // Create only 1 CorInfoImpl per thread.
+ // This allows SuperPMI to rely on non-reuse of handles in ObjectToHandle
CorInfoImpl corInfoImpl = _corInfoImpls.GetValue(Thread.CurrentThread, thread => new CorInfoImpl(this));
corInfoImpl.CompileMethod(methodCodeNodeNeedingCode);
}
if (Logger.IsVerbose)
Logger.Writer.WriteLine($"Warning: Method `{method}` was not compiled because `{ex.Message}` requires runtime JIT");
}
- });
+ };
+
+ // Use only main thread to compile if parallelism is 1. This allows SuperPMI to rely on non-reuse of handles in ObjectToHandle
+ if (_parallelism == 1)
+ {
+ foreach (var dependency in obj)
+ compileOneMethod(dependency);
+ }
+ else
+ {
+ ParallelOptions options = new ParallelOptions
+ {
+ MaxDegreeOfParallelism = _parallelism
+ };
+
+ Parallel.ForEach(obj, options, compileOneMethod);
+ }
}
if (_methodILCache.Count > 1000)