Skip to content
This repository was archived by the owner on Nov 1, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ protected virtual void FinalizeRuntimeSpecificStaticFieldLayout(TypeSystemContex
{
}

private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields)
protected static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields)
{
// Instance slice size is the total size of instance not including the base type.
// It is calculated as the field whose offset and size add to the greatest value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
public class ImportSectionNode : EmbeddedObjectNode
{
private readonly ArrayOfEmbeddedDataNode<Import> _imports;
private class ImportTable : ArrayOfEmbeddedDataNode<Import>
{
public ImportTable(string startSymbol, string endSymbol) : base(startSymbol, endSymbol, nodeSorter: null) {}

public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => false;
}

private readonly ImportTable _imports;
// TODO: annoying - today there's no way to put signature RVA's into R/O data section
private readonly ArrayOfEmbeddedPointersNode<Signature> _signatures;
// TODO: annoying - cannot enumerate the ArrayOfEmbeddedPointersNode so we must keep a copy.
Expand All @@ -34,7 +41,7 @@ public ImportSectionNode(string name, CorCompileImportType importType, CorCompil
_emitPrecode = emitPrecode;
_emitGCRefMap = emitGCRefMap;

_imports = new ArrayOfEmbeddedDataNode<Import>(_name + "_ImportBegin", _name + "_ImportEnd", null);
_imports = new ImportTable(_name + "_ImportBegin", _name + "_ImportEnd");
_signatures = new ArrayOfEmbeddedPointersNode<Signature>(_name + "_SigBegin", _name + "_SigEnd", null);
_signatureList = new List<Signature>();
_gcRefMap = (_emitGCRefMap ? new GCRefMapNode(this) : null);
Expand Down Expand Up @@ -78,20 +85,17 @@ public void AddImport(NodeFactory factory, Import import)

public override int ClassCode => -62839441;

public bool ShouldSkipEmittingTable(NodeFactory factory)
{
return _imports.ShouldSkipEmittingObjectNode(factory);
}

public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
{
if (!relocsOnly && _imports.ShouldSkipEmittingObjectNode(factory))
if (!_imports.ShouldSkipEmittingObjectNode(factory))
{
dataBuilder.EmitReloc(_imports.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, 0);
}
else
{
// Don't emit import section node at all if there are no entries in it
return;
dataBuilder.EmitUInt(0);
}

dataBuilder.EmitReloc(_imports.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, 0);
if (!relocsOnly)
{
dataBuilder.EmitInt(_imports.GetData(factory, false).Data.Length);
Expand All @@ -100,6 +104,7 @@ public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory f
dataBuilder.EmitByte((byte)_type);
dataBuilder.EmitByte(_entrySize);
}

if (!_signatures.ShouldSkipEmittingObjectNode(factory))
{
dataBuilder.EmitReloc(_signatures.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, No
int index = 0;
foreach (ImportSectionNode node in NodesList)
{
if (!relocsOnly && !node.ShouldSkipEmittingTable(factory))
if (!relocsOnly)
{
node.InitializeOffsetFromBeginningOfArray(builder.CountBytes);
node.InitializeIndexFromBeginningOfArray(index++);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,8 @@ private void EmitInstantiatedTypeSignature(InstantiatedType type, SignatureConte
{
EcmaModule targetModule = context.GetTargetModule(type);
EmitModuleOverride(targetModule, context);
context = context.InnerContext(targetModule);
EmitElementType(CorElementType.ELEMENT_TYPE_GENERICINST);
EmitTypeSignature(type.GetTypeDefinition(), context);
EmitTypeSignature(type.GetTypeDefinition(), context.InnerContext(targetModule));
EmitUInt((uint)type.Instantiation.Length);
for (int paramIndex = 0; paramIndex < type.Instantiation.Length; paramIndex++)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ private ISymbolNode CreateCctorTrigger(TypeDesc type, SignatureContext signature
{
return new DelayLoadHelperImport(
_codegenNodeFactory,
_codegenNodeFactory.DispatchImports,
_codegenNodeFactory.HelperImports,
ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_DelayLoad_Helper,
_codegenNodeFactory.TypeSignature(ReadyToRunFixupKind.READYTORUN_FIXUP_CctorTrigger, type, signatureContext));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
Expand Down Expand Up @@ -688,6 +687,11 @@ public void AddDynamicLayout(DefType instantiatedType, FieldAndOffset[] fieldMap

protected override ComputedInstanceFieldLayout ComputeInstanceFieldLayout(MetadataType type, int numInstanceFields)
{
if (type.IsExplicitLayout)
{
return ComputeExplicitFieldLayout(type, numInstanceFields);
}
else
if (type.IsValueType && (MarshalUtils.IsBlittableType(type) || MarshalUtils.IsManagedSequentialType(type)))
{
return ComputeSequentialFieldLayout(type, numInstanceFields);
Expand Down
2 changes: 1 addition & 1 deletion src/JitInterface/src/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2177,7 +2177,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET
}

#if READYTORUN
if (!_compilation.NodeFactory.CompilationModuleGroup.ContainsType(field.OwningType) &&
if (!_compilation.NodeFactory.CompilationModuleGroup.VersionsWithType(field.OwningType) &&
fieldAccessor == CORINFO_FIELD_ACCESSOR.CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER)
{
PreventRecursiveFieldInlinesOutsideVersionBubble(field, callerMethod);
Expand Down
102 changes: 102 additions & 0 deletions tests/src/Simple/ReadyToRunUnit/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;

internal class ClassWithStatic
Expand Down Expand Up @@ -136,7 +137,104 @@ private static bool BoxUnbox()
}
return success;
}

[StructLayout(LayoutKind.Explicit)]
private struct ExplicitFieldOffsetStruct
{
[FieldOffset(0)]
public int Field00;
[FieldOffset(0x0f)]
public int Field15;
}

private static ExplicitFieldOffsetStruct HelperCreateExplicitLayoutStruct()
{
ExplicitFieldOffsetStruct epl = new ExplicitFieldOffsetStruct();
epl.Field00 = 40;
epl.Field15 = 15;
return epl;
}

private static bool HelperCompare(ExplicitFieldOffsetStruct val, ExplicitFieldOffsetStruct val1)
{
bool match = true;
if (val.Field00 != val1.Field00)
{
match = false;
Console.WriteLine("ExplicitLayout: val.Field00 = {0}, val1.Field00 = {1}", val.Field00, val1.Field00);
}
if (val.Field15 != val1.Field15)
{
match = false;
Console.WriteLine("ExplicitLayout: val.Field15 = {0}, val1.Field15 = {1}", val.Field15, val1.Field15);
}
return match;
}

private static bool HelperCompare(ExplicitFieldOffsetStruct? val, ExplicitFieldOffsetStruct val1)
{
return val == null ? false : HelperCompare(val.Value, val1);
}

private static bool BoxUnboxToQ2(ExplicitFieldOffsetStruct? val)
{
return HelperCompare(val, HelperCreateExplicitLayoutStruct());
}

private static bool BoxUnboxToQ1(ValueType vt)
{
return BoxUnboxToQ2((ExplicitFieldOffsetStruct?)vt);
}

private static bool BoxUnboxToQ(object o)
{
return BoxUnboxToQ1((ValueType)o);
}

private static bool NullableWithExplicitLayoutTest()
{
ExplicitFieldOffsetStruct? s = HelperCreateExplicitLayoutStruct();
return BoxUnboxToQ(s);
}

private static char HelperCreateChar()
{
return 'c';
}

private static bool HelperCompare(char val, char val1)
{
if (val == val1)
{
return true;
}
Console.Error.WriteLine("val = {0} = 0x{1:x2}, val1 = {2} = 0x{3:x2}", val, (int)val, val1, (int)val1);
return false;
}

private static bool BoxUnboxToNQ2(char c)
{
return HelperCompare(c, HelperCreateChar());
}

private static bool BoxUnboxToNQ1(ValueType vt)
{
Console.WriteLine("BoxUnboxToNQ1: {0}", vt);
return BoxUnboxToNQ2((char)vt);
}

private static bool BoxUnboxToNQ(object o)
{
Console.WriteLine("BoxUnboxToNQ: {0}", o);
return BoxUnboxToNQ1((ValueType)o);
}

private static bool CastClassWithCharTest()
{
char? s = HelperCreateChar();
return BoxUnboxToNQ(s);
}

private static bool TypeHandle()
{
Console.WriteLine(TextFileName.GetType().ToString());
Expand Down Expand Up @@ -1063,6 +1161,10 @@ public static int Main(string[] args)
RunTest("ChkCast", ChkCast());
RunTest("ChkCastValueType", ChkCastValueType());
RunTest("BoxUnbox", BoxUnbox());
// TODO: enabling this test requires fixes to IsManagedSequential I'm going to send out
// in a subsequent PR together with removal of this temporary clause [trylek]
// RunTest("NullableWithExplicitLayoutTest", NullableWithExplicitLayoutTest());
RunTest("CastClassWithCharTest", CastClassWithCharTest());
RunTest("TypeHandle", TypeHandle());
RunTest("RuntimeTypeHandle", RuntimeTypeHandle());
RunTest("ReadAllText", ReadAllText());
Expand Down
6 changes: 6 additions & 0 deletions tests/src/tools/ReadyToRun.SuperIlc/CompilerRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ public ProcessParameters CompilationR2RDumpProcess(string compiledExecutable, bo
{
commonBuilder.Append($@" --rp ""{referencePath}""");
}

if (_options.CoreRootDirectory != null)
{
commonBuilder.Append($@" --rp ""{_options.CoreRootDirectory.FullName}""");
}

commonBuilder.Append($@" --in ""{compiledExecutable}""");

StringBuilder builder = new StringBuilder(commonBuilder.ToString());
Expand Down