diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs index 106b5d1c2242..e24feb5536de 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs @@ -190,8 +190,7 @@ internal static bool SupportsWritableData { get { - // For now just key this off of SupportsRelativePointer to avoid this on both CppCodegen and WASM. - return SupportsRelativePointers; + return true; } } @@ -1184,7 +1183,7 @@ internal void* WritableData uint offset = GetFieldOffset(EETypeField.ETF_WritableData); - if (!IsDynamicType) + if (!IsDynamicType && SupportsRelativePointers) return (void*)GetField(offset).Value; else return (void*)GetField(offset).Value; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/FrozenObjectHeapManager.Wasm.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/FrozenObjectHeapManager.Wasm.cs new file mode 100644 index 000000000000..d0c401011bbe --- /dev/null +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/FrozenObjectHeapManager.Wasm.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma warning disable IDE0060 // Remove unused parameter + +using System.Runtime.InteropServices; + +namespace Internal.Runtime +{ + internal unsafe partial class FrozenObjectHeapManager + { + private static void* ClrVirtualReserve(nuint size) + { + void* alloc = Interop.Sys.AlignedAlloc(8, size); + if (alloc != null) + { + NativeMemory.Clear(alloc, size); + } + return alloc; + } + + private static void* ClrVirtualCommit(void* pBase, nuint size) + { + // Already 'commited'. + return pBase; + } + + private static void ClrVirtualFree(void* pBase, nuint size) + { + // This will only be called before an OOM. We have no way to do a partial unmap, so do not try. + } + } +} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/FrozenObjectHeapManager.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/FrozenObjectHeapManager.cs index d81a5409bf42..8fbd3ec27fba 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/FrozenObjectHeapManager.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/FrozenObjectHeapManager.cs @@ -19,8 +19,13 @@ internal unsafe partial class FrozenObjectHeapManager private readonly LowLevelLock m_Crst = new LowLevelLock(); private FrozenObjectSegment m_CurrentSegment; +#if TARGET_WASM + // WASM doesn't support reserving memory so we use a smaller size. + private const nuint FOH_SEGMENT_DEFAULT_SIZE = 64 * 1024; +#else // Default size to reserve for a frozen segment private const nuint FOH_SEGMENT_DEFAULT_SIZE = 4 * 1024 * 1024; +#endif // Size to commit on demand in that reserved space private const nuint FOH_COMMIT_SIZE = 64 * 1024; @@ -119,7 +124,7 @@ public FrozenObjectSegment(nuint sizeHint) { m_Size = sizeHint; - Debug.Assert(m_Size > FOH_COMMIT_SIZE); + Debug.Assert(m_Size >= FOH_COMMIT_SIZE); Debug.Assert(m_Size % FOH_COMMIT_SIZE == 0); void* alloc = ClrVirtualReserve(m_Size); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 97bdc85c3edf..8ba7b7b640bd 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -307,7 +307,8 @@ - + + diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index e136b1057cf1..48ee9cbc18a2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -103,8 +103,7 @@ public EETypeNode(NodeFactory factory, TypeDesc type) factory.TypeSystemContext.EnsureLoadableType(type); } - public static bool SupportsWritableData(TargetDetails target) - => target.SupportsRelativePointers; + public static bool SupportsWritableData(TargetDetails target) => true; public static bool SupportsFrozenRuntimeTypeInstances(TargetDetails target) => SupportsWritableData(target); @@ -1125,11 +1124,17 @@ protected void OutputWritableData(NodeFactory factory, ref ObjectDataBuilder obj { if (_writableDataNode != null) { - objData.EmitReloc(_writableDataNode, RelocType.IMAGE_REL_BASED_RELPTR32); + if (factory.Target.SupportsRelativePointers) + objData.EmitReloc(_writableDataNode, RelocType.IMAGE_REL_BASED_RELPTR32); + else + objData.EmitPointerReloc(_writableDataNode); } else if (SupportsWritableData(factory.Target)) { - objData.EmitInt(0); + if (factory.Target.SupportsRelativePointers) + objData.EmitInt(0); + else + objData.EmitZeroPointer(); } } diff --git a/src/coreclr/tools/aot/ILCompiler.LLVM/CodeGen/LLVMObjectWriter.cs b/src/coreclr/tools/aot/ILCompiler.LLVM/CodeGen/LLVMObjectWriter.cs index c145c72524e5..2653826f475e 100644 --- a/src/coreclr/tools/aot/ILCompiler.LLVM/CodeGen/LLVMObjectWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.LLVM/CodeGen/LLVMObjectWriter.cs @@ -248,6 +248,8 @@ private void EmitObjectNode(ObjectNode node, ObjectData nodeContents) if (nextRelocValid) { Relocation reloc = nodeContents.Relocs[relocIndex]; + Debug.Assert(IsSupportedRelocType(node, reloc.RelocType), $"{reloc.RelocType} in {node} not supported"); + long delta; fixed (void* location = &data[reloc.Offset]) { @@ -313,6 +315,16 @@ private void EmitObjectNode(ObjectNode node, ObjectData nodeContents) } } + private static bool IsSupportedRelocType(ObjectNode node, RelocType type) + { + if (node is StackTraceMethodMappingNode) + { + // Stack trace metadata uses relative pointers, but is currently unused. + return true; + } + return type is RelocType.IMAGE_REL_BASED_HIGHLOW; + } + private void EmitSymbolDef(LLVMValueRef baseSymbol, ReadOnlySpan symbolIdentifier, int offsetFromBaseSymbol) { LLVMValueRef symbolAddress = baseSymbol; diff --git a/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.cs b/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.cs index 62c6f5211a94..5252e1f2d58c 100644 --- a/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.cs +++ b/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.cs @@ -55,9 +55,7 @@ private static int Main() TestReadOnlySpan.Run(); TestStaticInterfaceMethod.Run(); TestConstrainedCall.Run(); -#if !CODEGEN_WASM TestTypeHandles.Run(); -#endif TestIsValueType.Run(); TestIndirectLoads.Run(); TestInitBlock.Run();