|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using Microsoft.Diagnostics.DataContractReader.Data;
namespace Microsoft.Diagnostics.DataContractReader.Contracts;
internal readonly partial struct ReJIT_1 : IReJIT
{
internal readonly Target _target;
private readonly Data.ProfControlBlock _profControlBlock;
// see src/coreclr/inc/corprof.idl
[Flags]
private enum COR_PRF_MONITOR
{
COR_PRF_ENABLE_REJIT = 0x00040000,
}
// see src/coreclr/vm/codeversion.h
[Flags]
public enum RejitFlags : uint
{
kStateRequested = 0x00000000,
kStateActive = 0x00000002,
kStateMask = 0x0000000F
}
public ReJIT_1(Target target)
{
_target = target;
TargetPointer profControlBlockAddress = target.ReadGlobalPointer(Constants.Globals.ProfilerControlBlock);
_profControlBlock = target.ProcessedData.GetOrAdd<Data.ProfControlBlock>(profControlBlockAddress);
}
bool IReJIT.IsEnabled()
{
bool profEnabledReJIT = (_profControlBlock.GlobalEventMask & (ulong)COR_PRF_MONITOR.COR_PRF_ENABLE_REJIT) != 0;
return profEnabledReJIT || _profControlBlock.RejitOnAttachEnabled;
}
RejitState IReJIT.GetRejitState(ILCodeVersionHandle ilCodeVersionHandle)
{
if (!ilCodeVersionHandle.IsExplicit)
{
// for non explicit ILCodeVersions, ReJITState is always kStateActive
return RejitState.Active;
}
ILCodeVersionNode ilCodeVersionNode = AsNode(ilCodeVersionHandle);
return ((RejitFlags)ilCodeVersionNode.RejitState & RejitFlags.kStateMask) switch
{
RejitFlags.kStateRequested => RejitState.Requested,
RejitFlags.kStateActive => RejitState.Active,
_ => throw new InvalidOperationException($"Unknown ReJIT state: {ilCodeVersionNode.RejitState}"),
};
}
TargetNUInt IReJIT.GetRejitId(ILCodeVersionHandle ilCodeVersionHandle)
{
if (ilCodeVersionHandle.ILCodeVersionNode == TargetPointer.Null)
{
// for non explicit ILCodeVersions, ReJITId is always 0
return new TargetNUInt(0);
}
ILCodeVersionNode ilCodeVersionNode = AsNode(ilCodeVersionHandle);
return ilCodeVersionNode.VersionId;
}
private ILCodeVersionNode AsNode(ILCodeVersionHandle ilCodeVersionHandle)
{
if (ilCodeVersionHandle.ILCodeVersionNode == TargetPointer.Null)
{
throw new InvalidOperationException("Synthetic ILCodeVersion does not have a backing node.");
}
return _target.ProcessedData.GetOrAdd<ILCodeVersionNode>(ilCodeVersionHandle.ILCodeVersionNode);
}
}
|