Skip to content
This repository was archived by the owner on Nov 1, 2020. It is now read-only.
Closed
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
14 changes: 14 additions & 0 deletions src/ILCompiler.Compiler/src/Compiler/Compilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,20 @@ public ObjectNode GetFieldRvaData(FieldDesc field)
}
}

public ISymbolNode GetFieldData(FieldDesc field)
{
if (field.HasRva)
{
return (ISymbolNode)GetFieldRvaData(field);
}
else
{
Debug.Assert(field.IsStatic && !field.IsThreadStatic && !field.HasGCStaticBase);
ISymbolNode baseAddr = NodeFactory.TypeNonGCStaticsSymbol((MetadataType)field.OwningType);
return NodeFactory.SymbolWithOffset(baseAddr, field.Offset.AsInt);
}
}

public bool HasLazyStaticConstructor(TypeDesc type)
{
return TypeSystemContext.HasLazyStaticConstructor(type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,11 @@ private void CreateNodeCaches()
return new NamedJumpStubNode(id.Item1, id.Item2);
});

_symbolWithOffsetNodes = new NodeCache<SymbolWithOffsetKey, SymbolWithOffsetNode>((SymbolWithOffsetKey key) =>
{
return new SymbolWithOffsetNode(key.Symbol, key.Offset);
});

_vTableNodes = new NodeCache<TypeDesc, VTableSliceNode>((TypeDesc type ) =>
{
if (CompilationModuleGroup.ShouldProduceFullVTable(type))
Expand Down Expand Up @@ -975,7 +980,14 @@ public ISymbolNode NamedJumpStub(string name, ISymbolNode target)
{
return _namedJumpStubNodes.GetOrAdd(new Tuple<string, ISymbolNode>(name, target));
}


private NodeCache<SymbolWithOffsetKey, SymbolWithOffsetNode> _symbolWithOffsetNodes;

public ISymbolNode SymbolWithOffset(ISymbolNode symbol, int offset)
{
return _symbolWithOffsetNodes.GetOrAdd(new SymbolWithOffsetKey(symbol, offset));
}

/// <summary>
/// Returns alternative symbol name that object writer should produce for given symbols
/// in addition to the regular one.
Expand Down Expand Up @@ -1145,6 +1157,27 @@ public override int GetHashCode()
}
}

protected struct SymbolWithOffsetKey : IEquatable<SymbolWithOffsetKey>
{
public readonly ISymbolNode Symbol;
public readonly int Offset;

public SymbolWithOffsetKey(ISymbolNode symbol, int offset)
{
Symbol = symbol;
Offset = offset;
}

public bool Equals(SymbolWithOffsetKey other) => Symbol == other.Symbol && Offset == other.Offset;
public override bool Equals(object obj) => obj is SymbolWithOffsetKey && Equals((SymbolWithOffsetKey)obj);
public override int GetHashCode()
{
int hashCode = Symbol.GetHashCode();
hashCode = hashCode * 23 + Offset;
return hashCode;
}
}

protected struct ReadOnlyDataBlobKey : IEquatable<ReadOnlyDataBlobKey>
{
public readonly Utf8String Name;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;

using ILCompiler.DependencyAnalysisFramework;

using Internal.Text;

namespace ILCompiler.DependencyAnalysis
{
internal class SymbolWithOffsetNode : DependencyNodeCore<NodeFactory>, ISymbolNode
{
private ISymbolNode _target;
private int _offset;

public SymbolWithOffsetNode(ISymbolNode target, int offset)
{
_target = target;
_offset = offset;
}

public int Offset => _offset;

public override bool InterestingForDynamicDependencyAnalysis => false;
public override bool HasDynamicDependencies => false;
public override bool HasConditionalStaticDependencies => false;
public override bool StaticDependenciesAreComputed => true;
public bool RepresentsIndirectionCell => false;

public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
_target.AppendMangledName(nameMangler, sb);
}

public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory context)
{
return null;
}

public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory context)
{
return new DependencyListEntry[]
{
new DependencyListEntry(_target, "Target"),
};
}

public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory context)
{
return null;
}

protected override string GetName(NodeFactory context)
{
return "__offs_" + _offset.ToStringInvariant() + "_from_" + _target.GetMangledName(context.NameMangler);
}
}
}
1 change: 1 addition & 0 deletions src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
<Compile Include="Compiler\DependencyAnalysis\MrtProcessedExportAddressTableNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\MrtProcessedImportAddressTableNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\RuntimeDecodableJumpStub.cs" />
<Compile Include="Compiler\DependencyAnalysis\SymbolWithOffsetNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\WindowsDebugILImagesSection.cs" />
<Compile Include="Compiler\DependencyAnalysis\WindowsDebugManagedNativeDictionaryInfoSection.cs" />
<Compile Include="Compiler\DependencyAnalysis\WindowsDebugMergedAssemblyRecordsSection.cs" />
Expand Down
43 changes: 24 additions & 19 deletions src/JitInterface/src/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2162,9 +2162,8 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET
pResult.fieldLookup = CreateConstLookupToSymbol(helper);
}
}
else
else if (field.IsThreadStatic || field.HasGCStaticBase)
{

fieldAccessor = CORINFO_FIELD_ACCESSOR.CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER;
pResult.helper = CorInfoHelpFunc.CORINFO_HELP_READYTORUN_STATIC_BASE;

Expand All @@ -2173,30 +2172,37 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET
{
helperId = ReadyToRunHelperId.GetThreadStaticBase;
}
else if (field.HasGCStaticBase)
{
helperId = ReadyToRunHelperId.GetGCStaticBase;
}
else
{
var owningType = field.OwningType;
if ((owningType.IsWellKnownType(WellKnownType.IntPtr) ||
owningType.IsWellKnownType(WellKnownType.UIntPtr)) &&
field.Name == "Zero")
{
fieldAccessor = CORINFO_FIELD_ACCESSOR.CORINFO_FIELD_INTRINSIC_ZERO;
}
else
{
helperId = ReadyToRunHelperId.GetNonGCStaticBase;
}
Debug.Assert(field.HasGCStaticBase);
helperId = ReadyToRunHelperId.GetGCStaticBase;
}

if (helperId != ReadyToRunHelperId.Invalid)
{
pResult.fieldLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ReadyToRunHelper(helperId, field.OwningType));
}
}
else
{
var owningType = field.OwningType;
if ((owningType.IsWellKnownType(WellKnownType.IntPtr) ||
owningType.IsWellKnownType(WellKnownType.UIntPtr)) &&
field.Name == "Zero")
{
fieldAccessor = CORINFO_FIELD_ACCESSOR.CORINFO_FIELD_INTRINSIC_ZERO;
}
else
{
fieldAccessor = CORINFO_FIELD_ACCESSOR.CORINFO_FIELD_STATIC_ADDRESS;

// We are not going through a helper. The constructor has to be triggered explicitly.
if (_compilation.HasLazyStaticConstructor(field.OwningType))
{
fieldFlags |= CORINFO_FIELD_FLAGS.CORINFO_FLG_FIELD_INITCLASS;
}
}
}
}
else
{
Expand Down Expand Up @@ -3416,8 +3422,7 @@ private uint getClassDomainID(CORINFO_CLASS_STRUCT_* cls, ref void* ppIndirectio
private void* getFieldAddress(CORINFO_FIELD_STRUCT_* field, ref void* ppIndirection)
{
FieldDesc fieldDesc = HandleToObject(field);
Debug.Assert(fieldDesc.HasRva);
return (void*)ObjectToHandle(_compilation.GetFieldRvaData(fieldDesc));
return (void*)ObjectToHandle(_compilation.GetFieldData(fieldDesc));
}

private IntPtr getVarArgsHandle(CORINFO_SIG_INFO* pSig, ref void* ppIndirection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ public ObjectNode GetFieldRvaData(FieldDesc field)
throw new NotImplementedException();
}

public ObjectNode GetFieldData(FieldDesc field)
{
throw new NotImplementedException();
}

internal MethodIL GetMethodIL(MethodDesc method)
{
// Flush the cache when it grows too big
Expand Down