--- /dev/null
+// 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.Diagnostics;
+using System.Reflection.Metadata;
+
+using Internal.TypeSystem;
+using Internal.TypeSystem.Ecma;
+
+using Debug = System.Diagnostics.Debug;
+
+namespace ILCompiler
+{
+ public static class AssemblyExtensions
+ {
+ /// <summary>
+ /// Determines whether the assembly was compiled without optimizations using the DebuggableAttribute
+ /// </summary>
+ public static bool HasOptimizationsDisabled(this EcmaAssembly assembly)
+ {
+ bool result = false;
+ MetadataReader reader = assembly.MetadataReader;
+ var attributeHandles = assembly.AssemblyDefinition.GetCustomAttributes();
+ CustomAttributeHandle attributeHandle = reader.GetCustomAttributeHandle(attributeHandles, "System.Diagnostics", "DebuggableAttribute");
+ if (!attributeHandle.IsNil)
+ {
+ CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle);
+ CustomAttributeValue<TypeDesc> decoded = attribute.DecodeValue(new CustomAttributeTypeProvider(assembly));
+
+ if (decoded.FixedArguments.Length == 1)
+ {
+ // DebuggableAttribute( DebuggableAttribute.DebuggingModes modes )
+ if (!(decoded.FixedArguments[0].Value is int))
+ {
+ ThrowHelper.ThrowBadImageFormatException();
+ }
+ DebuggableAttribute.DebuggingModes modes = (DebuggableAttribute.DebuggingModes)decoded.FixedArguments[0].Value;
+ result = modes.HasFlag(DebuggableAttribute.DebuggingModes.DisableOptimizations) && modes.HasFlag(DebuggableAttribute.DebuggingModes.Default);
+ }
+ else if (decoded.FixedArguments.Length == 2)
+ {
+ // DebuggableAttribute( bool isJITTrackingEnabled, bool isJITOptimizerDisabled )
+ if (!(decoded.FixedArguments[0].Value is bool) || !(decoded.FixedArguments[1].Value is bool))
+ {
+ ThrowHelper.ThrowBadImageFormatException();
+ }
+ result = ((bool)decoded.FixedArguments[1].Value);
+ }
+ }
+ return result;
+ }
+ }
+}
// On X86 the Array address method doesn't use IL stubs, and instead has a custom calling convention
if ((method.Context.Target.Architecture == TargetArchitecture.X86) &&
- (method.IsArrayAddressMethod()) &&
- method.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Any))
+ method.IsArrayAddressMethod())
{
hasParamType = true;
}
<Compile Include="..\..\Common\JitInterface\CorInfoTypes.VarInfo.cs" Link="JitInterface\CorInfoTypes.VarInfo.cs" />
<Compile Include="..\..\Common\JitInterface\SystemVStructClassificator.cs" Link="JitInterface\SystemVStructClassificator.cs" />
<Compile Include="..\..\Common\TypeSystem\Interop\InteropTypes.cs" Link="Interop\InteropTypes.cs" />
+ <Compile Include="Compiler\AssemblyExtensions.cs" />
<Compile Include="Compiler\DependencyAnalysis\ReadyToRun\DelayLoadMethodCallThunkNodeRange.cs" />
<Compile Include="ObjectWriter\MapFileBuilder.cs" />
<Compile Include="CodeGen\ReadyToRunObjectWriter.cs" />
public string CompositeRootPath;
public bool Optimize;
+ public bool OptimizeDisabled;
public bool OptimizeSpace;
public bool OptimizeTime;
public bool InputBubble;
syntax.DefineOption("o|out|outputfilepath", ref OutputFilePath, SR.OutputFilePath);
syntax.DefineOption("crp|compositerootpath", ref CompositeRootPath, SR.CompositeRootPath);
syntax.DefineOption("O|optimize", ref Optimize, SR.EnableOptimizationsOption);
+ syntax.DefineOption("Od|optimize-disabled", ref OptimizeDisabled, SR.DisableOptimizationsOption);
syntax.DefineOption("Os|optimize-space", ref OptimizeSpace, SR.OptimizeSpaceOption);
syntax.DefineOption("Ot|optimize-time", ref OptimizeTime, SR.OptimizeSpeedOption);
syntax.DefineOption("inputbubble", ref InputBubble, SR.InputBubbleOption);
using System;
using System.Collections.Generic;
using System.IO;
+using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Runtime.InteropServices;
}
_optimizationMode = OptimizationMode.None;
- if (_commandLineOptions.OptimizeSpace)
+ if (_commandLineOptions.OptimizeDisabled)
+ {
+ if (_commandLineOptions.Optimize || _commandLineOptions.OptimizeSpace || _commandLineOptions.OptimizeTime)
+ Console.WriteLine(SR.WarningOverridingOptimize);
+ }
+ else if (_commandLineOptions.OptimizeSpace)
{
if (_commandLineOptions.OptimizeTime)
Console.WriteLine(SR.WarningOverridingOptimizeSpace);
}
}
}
+ // In single-file compilation mode, use the assembly's DebuggableAttribute to determine whether to optimize
+ // or produce debuggable code if an explicit optimization level was not specified on the command line
+ if (_optimizationMode == OptimizationMode.None && !_commandLineOptions.OptimizeDisabled && !_commandLineOptions.Composite)
+ {
+ System.Diagnostics.Debug.Assert(inputModules.Count == 1);
+ _optimizationMode = ((EcmaAssembly)inputModules[0].Assembly).HasOptimizationsDisabled() ? OptimizationMode.None : OptimizationMode.Blended;
+ }
//
// Compile
<data name="MapCsvFileOption" xml:space="preserve">
<value>Generate a CSV formatted map file</value>
</data>
+ <data name="DisableOptimizationsOption" xml:space="preserve">
+ <value>Disable optimizations to simplify debugging</value>
+ </data>
+ <data name="WarningOverridingOptimize" xml:space="preserve">
+ <value>Warning: -Od overrides other optimization options</value>
+ </data>
</root>
\ No newline at end of file
echo -r:$CORE_ROOT/mscorlib.dll>>$__ResponseFile
echo --verify-type-and-field-layout>>$__ResponseFile
echo --targetarch:$(TargetArchitecture)>>$__ResponseFile
- echo -O>>$__ResponseFile
echo "Response file: $__ResponseFile"
cat $__ResponseFile
echo -o:!__OutputFile!>>!__ResponseFile!
echo --targetarch:$(TargetArchitecture)>>!__ResponseFile!
echo --verify-type-and-field-layout>>!__ResponseFile!
- echo -O>>!__ResponseFile!
echo -r:!CORE_ROOT!\System.*.dll>>!__ResponseFile!
echo -r:!CORE_ROOT!\Microsoft.*.dll>>!__ResponseFile!
echo -r:!CORE_ROOT!\mscorlib.dll>>!__ResponseFile!