Skip to content
Open
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
36 changes: 27 additions & 9 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1173,15 +1173,23 @@ void Compiler::eeAllocMem(AllocMemChunk& codeChunk,

for (unsigned i = 0; i < numDataChunks; i++)
{
// Increase size of the hot code chunk and store offset in data chunk
AllocMemChunk& codeChunk = chunks.BottomRef(0);
if ((dataChunks[i].flags & CORJIT_ALLOCMEM_HAS_POINTERS_TO_CODE) != 0)
{
// These are always passed to the EE as separate chunks since their relocations need special treatment
chunks.Push(dataChunks[i]);
}
else
{
// Increase size of the hot code chunk and store offset in data chunk
AllocMemChunk& codeChunk = chunks.BottomRef(0);

codeChunk.size = AlignUp(codeChunk.size, dataChunks[i].alignment);
dataChunks[i].block = (uint8_t*)(uintptr_t)codeChunk.size;
dataChunks[i].blockRW = (uint8_t*)(uintptr_t)codeChunk.size;
codeChunk.size += dataChunks[i].size;
codeChunk.size = AlignUp(codeChunk.size, dataChunks[i].alignment);
dataChunks[i].block = (uint8_t*)(uintptr_t)codeChunk.size;
dataChunks[i].blockRW = (uint8_t*)(uintptr_t)codeChunk.size;
codeChunk.size += dataChunks[i].size;

codeChunk.alignment = max(codeChunk.alignment, dataChunks[i].alignment);
codeChunk.alignment = max(codeChunk.alignment, dataChunks[i].alignment);
}
}

#else
Expand Down Expand Up @@ -1228,8 +1236,18 @@ void Compiler::eeAllocMem(AllocMemChunk& codeChunk,
// Fix up data section pointers.
for (unsigned i = 0; i < numDataChunks; i++)
{
dataChunks[i].block = codeChunk.block + (size_t)dataChunks[i].block;
dataChunks[i].blockRW = codeChunk.blockRW + (size_t)dataChunks[i].blockRW;
if ((dataChunks[i].flags & CORJIT_ALLOCMEM_HAS_POINTERS_TO_CODE) != 0)
{
// These are always passed to the EE as separate chunks since their relocations need special treatment
dataChunks[i].block = chunks.BottomRef(curDataChunk).block;
dataChunks[i].blockRW = chunks.BottomRef(curDataChunk).blockRW;
curDataChunk++;
}
else
{
dataChunks[i].block = codeChunk.block + (size_t)dataChunks[i].block;
dataChunks[i].blockRW = codeChunk.blockRW + (size_t)dataChunks[i].blockRW;
}
}
Comment on lines +1239 to 1251
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW: it seems questionable whether we need this "put into .text" behavior at all. And if we do (due to distance constraints), then presumably we could hit problems for async resumption info too.

If we end up with the optimization to fold common read only data then we will probably want to disable this so that it also kicks in for arm64.


#else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ public override bool ShouldSkipEmittingObjectNode(NodeFactory factory)
}
#endif

// TODO: (async) This should stay RO everywhere: https://github.com/dotnet/runtime/issues/121871
public override ObjectNodeSection GetSection(NodeFactory factory)
=> factory.Target.IsWindows ? ObjectNodeSection.ReadOnlyDataSection : ObjectNodeSection.DataSection;
=> ObjectNodeSection.ReadOnlyDataSection;

public override bool StaticDependenciesAreComputed => _data != null;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;

using Internal.Text;
using Internal.TypeSystem;

namespace ILCompiler.DependencyAnalysis
{
public class MethodReadWriteDataNode : ObjectNode, ISymbolDefinitionNode
{
private MethodDesc _owningMethod;
private ObjectData _data;

public MethodReadWriteDataNode(MethodDesc owningMethod)
{
_owningMethod = owningMethod;
}

#if !READYTORUN
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory)
{
IMethodNode owningBody = factory.MethodEntrypoint(_owningMethod);
return factory.ObjectInterner.GetDeduplicatedSymbol(factory, owningBody) != owningBody;
}
#endif

public override ObjectNodeSection GetSection(NodeFactory factory)
=> ObjectNodeSection.DataSection;

public override bool StaticDependenciesAreComputed => _data != null;

public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append("__readwritedata_"u8).Append(nameMangler.GetMangledMethodName(_owningMethod));
}
public int Offset => 0;
public override bool IsShareable => true;

public void InitializeData(ObjectData data)
{
Debug.Assert(_data == null);
_data = data;
}

public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
return _data;
}

protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);

#if !SUPPORT_JIT
public override int ClassCode => 689723708;

public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
{
return comparer.Compare(_owningMethod, ((MethodReadWriteDataNode)other)._owningMethod);
}
#endif
}
}
94 changes: 93 additions & 1 deletion src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ private CompilationResult CompileMethodInternal(IMethodNode methodCodeNodeNeedin

PublishCode();
PublishROData();
PublishRWData();

return CompilationResult.CompilationComplete;
}
Expand Down Expand Up @@ -599,6 +600,23 @@ private void PublishROData()
_roDataBlob.InitializeData(objectData);
}

private void PublishRWData()
{
if (_rwDataBlob == null)
{
return;
}

var relocs = _rwDataRelocs.ToArray();
Array.Sort(relocs, (x, y) => (x.Offset - y.Offset));
var objectData = new ObjectNode.ObjectData(_rwData,
relocs,
_rwDataAlignment,
new ISymbolDefinitionNode[] { _rwDataBlob });

_rwDataBlob.InitializeData(objectData);
}

private MethodDesc MethodBeingCompiled
{
get
Expand Down Expand Up @@ -653,8 +671,12 @@ private void CompileMethodCleanup()
_roData = null;
_roDataBlob = null;

_rwData = null;
_rwDataBlob = null;

_codeRelocs = default(ArrayBuilder<Relocation>);
_roDataRelocs = default(ArrayBuilder<Relocation>);
_rwDataRelocs = default(ArrayBuilder<Relocation>);
#if READYTORUN
_coldCodeRelocs = default(ArrayBuilder<Relocation>);
#endif
Expand Down Expand Up @@ -3799,6 +3821,10 @@ private bool getTailCallHelpers(ref CORINFO_RESOLVED_TOKEN callToken, CORINFO_SI
private MethodReadOnlyDataNode _roDataBlob;
private int _roDataAlignment;

private byte[] _rwData;
private MethodReadWriteDataNode _rwDataBlob;
private int _rwDataAlignment;

private int _numFrameInfos;
private int _usedFrameInfos;
private FrameInfo[] _frameInfos;
Expand All @@ -3819,9 +3845,16 @@ private void allocMem(ref AllocMemArgs args)
Span<AllocMemChunk> chunks = new Span<AllocMemChunk>(args.chunks, checked((int)args.chunksCount));

uint roDataSize = 0;
uint rwDataSize = 0;

_codeAlignment = -1;
_roDataAlignment = -1;
_rwDataAlignment = -1;

// ELF/MachO do not support relocations from read-only sections to code sections, so we must put these
// into read-write sections.
bool ChunkNeedsReadWriteSection(in AllocMemChunk chunk)
=> (chunk.flags & CorJitAllocMemFlag.CORJIT_ALLOCMEM_HAS_POINTERS_TO_CODE) != 0 && !_compilation.TypeSystemContext.Target.IsWindows;

foreach (ref AllocMemChunk chunk in chunks)
{
Expand All @@ -3840,6 +3873,13 @@ private void allocMem(ref AllocMemArgs args)
_methodColdCodeNode = new MethodColdCodeNode(MethodBeingCompiled);
#endif
}
else if (ChunkNeedsReadWriteSection(chunk))
{
// For ELF/MachO we need to put data containing relocations into .text into a RW section
rwDataSize = (uint)((int)rwDataSize).AlignUp((int)chunk.alignment);
rwDataSize += chunk.size;
_rwDataAlignment = Math.Max(_rwDataAlignment, (int)chunk.alignment);
}
else
{
roDataSize = (uint)((int)roDataSize).AlignUp((int)chunk.alignment);
Expand All @@ -3862,6 +3902,11 @@ private void allocMem(ref AllocMemArgs args)
continue;
}

if (ChunkNeedsReadWriteSection(chunk))
{
continue;
}

offset = offset.AlignUp((int)chunk.alignment);
chunk.block = roDataBlock + offset;
chunk.blockRW = chunk.block;
Expand All @@ -3871,6 +3916,31 @@ private void allocMem(ref AllocMemArgs args)
Debug.Assert(offset <= roDataSize);
}

if (rwDataSize != 0)
{
_rwData = new byte[rwDataSize];
_rwDataBlob = new MethodReadWriteDataNode(MethodBeingCompiled);
byte* rwDataBlock = (byte*)GetPin(_rwData);
int offset = 0;

foreach (ref AllocMemChunk chunk in chunks)
{
if ((chunk.flags & (CorJitAllocMemFlag.CORJIT_ALLOCMEM_HOT_CODE | CorJitAllocMemFlag.CORJIT_ALLOCMEM_COLD_CODE)) != 0)
{
continue;
}
if (ChunkNeedsReadWriteSection(chunk))
{
offset = offset.AlignUp((int)chunk.alignment);
chunk.block = rwDataBlock + offset;
chunk.blockRW = chunk.block;
offset += (int)chunk.size;
}
}

Debug.Assert(offset <= rwDataSize);
}

if (_numFrameInfos > 0)
{
_frameInfos = new FrameInfo[_numFrameInfos];
Expand Down Expand Up @@ -3982,6 +4052,7 @@ private void recordCallSite(uint instrOffset, CORINFO_SIG_INFO* callSig, CORINFO

private ArrayBuilder<Relocation> _codeRelocs;
private ArrayBuilder<Relocation> _roDataRelocs;
private ArrayBuilder<Relocation> _rwDataRelocs;
#if READYTORUN
private ArrayBuilder<Relocation> _coldCodeRelocs;
#endif
Expand All @@ -3999,8 +4070,10 @@ public enum BlockType : sbyte
ColdCode = 1,
/// <summary>Read-only data.</summary>
ROData = 2,
/// <summary>Read-write data.</summary>
RWData = 3,
/// <summary>Instrumented Block Count Data</summary>
BBCounts = 3
BBCounts = 4
}

private BlockType findKnownBlock(void* location, out int offset)
Expand Down Expand Up @@ -4038,6 +4111,18 @@ private BlockType findKnownBlock(void* location, out int offset)
}
}

if (_rwData != null)
{
fixed (byte* pRWData = _rwData)
{
if (pRWData <= (byte*)location && (byte*)location < pRWData + _rwData.Length)
{
offset = (int)((byte*)location - pRWData);
return BlockType.RWData;
}
}
}

{
BlockType retBlockType = BlockType.Unknown;
offset = 0;
Expand All @@ -4062,6 +4147,9 @@ private ref ArrayBuilder<Relocation> findRelocBlock(BlockType blockType, out int
case BlockType.ROData:
length = _roData.Length;
return ref _roDataRelocs;
case BlockType.RWData:
length = _rwData.Length;
return ref _rwDataRelocs;
#if READYTORUN
case BlockType.ColdCode:
length = _coldCode.Length;
Expand Down Expand Up @@ -4132,6 +4220,10 @@ private void recordRelocation(void* location, void* locationRW, void* target, Co
relocTarget = _roDataBlob;
break;

case BlockType.RWData:
relocTarget = _rwDataBlob;
break;

#if READYTORUN
case BlockType.BBCounts:
relocTarget = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ObjectNodeSection.cs" Link="Compiler\DependencyAnalysis\ObjectNodeSection.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\Relocation.cs" Link="Compiler\DependencyAnalysis\Relocation.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\MethodReadOnlyDataNode.cs" Link="Compiler\DependencyAnalysis\MethodReadOnlyDataNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\MethodReadWriteDataNode.cs" Link="Compiler\DependencyAnalysis\MethodReadWriteDataNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ShadowConcreteMethodNode.cs" Link="Compiler\DependencyAnalysis\ShadowConcreteMethodNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ShadowNonConcreteMethodNode.cs" Link="Compiler\DependencyAnalysis\ShadowNonConcreteMethodNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ShadowMethodNode.cs" Link="Compiler\DependencyAnalysis\ShadowMethodNode.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ObjectNodeSection.cs" Link="Compiler\DependencyAnalysis\ObjectNodeSection.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\Relocation.cs" Link="Compiler\DependencyAnalysis\Relocation.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\MethodReadOnlyDataNode.cs" Link="Compiler\DependencyAnalysis\MethodReadOnlyDataNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\MethodReadWriteDataNode.cs" Link="Compiler\DependencyAnalysis\MethodReadWriteDataNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ShadowConcreteMethodNode.cs" Link="Compiler\DependencyAnalysis\ShadowConcreteMethodNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ShadowMethodNode.cs" Link="Compiler\DependencyAnalysis\ShadowMethodNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\SortableDependencyNode.cs" Link="Compiler\DependencyAnalysis\SortableDependencyNode.cs" />
Expand Down
6 changes: 0 additions & 6 deletions src/tests/async/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,5 @@
<!-- disable building for configurations that do not yet support runtime async. -->
<DisableProjectBuild Condition="'$(RuntimeFlavor)' == 'mono' or '$(TargetArchitecture)' == 'wasm'">true</DisableProjectBuild>
</PropertyGroup>

<PropertyGroup>
<!-- https://github.com/dotnet/runtime/issues/121871 -->
<DisableProjectBuild Condition="'$(TestBuildMode)' == 'nativeaot' and '$(TargetArchitecture)' == 'arm64'">true</DisableProjectBuild>
</PropertyGroup>

<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.targets, $(MSBuildThisFileDirectory)..))" />
</Project>
4 changes: 0 additions & 4 deletions src/tests/nativeaot/SmokeTests/UnitTests/UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@

<IlcOrderFile>order.txt</IlcOrderFile>
<StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
</PropertyGroup>

<!-- Enable runtime async; delete this block once it's on by default -->
<!-- Conditioned to x64 only due to https://github.com/dotnet/runtime/issues/121871 -->
<PropertyGroup Condition="'$(TargetArchitecture)' == 'x64'">
<Features>$(Features);runtime-async=on</Features>
</PropertyGroup>

Expand Down
Loading