diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index d1ea61f025f9..81d474349d49 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -588,8 +588,6 @@ The .NET Foundation licenses this file to you under the MIT license. - - @@ -601,13 +599,15 @@ The .NET Foundation licenses this file to you under the MIT license. - - - - + + - + + + + + diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.wasm.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.wasm.cs index 18168f11c6cd..534e663f7cd6 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.wasm.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.wasm.cs @@ -96,7 +96,7 @@ private static void DispatchException(object exception, RhEHFrameType flags) } else { - if (ShouldTypedClauseCatchThisException(exception, clause.ClauseType, false /* tryUnwrapException, not used for NATIVEAOT */)) + if (ShouldTypedClauseCatchThisException(exception, clause.ClauseType)) { goto FoundHandler; } @@ -869,4 +869,98 @@ public static int Parse(byte* pUnwindInfo, uint* pShadowFrameSize = null, void** return (int)(pCurrent - pUnwindInfo); } } + + // TODO-LLVM-Upstream: create ExceptionHandling.Common.cs and put the things below there. + internal static unsafe partial class EH + { + private enum RhEHFrameType + { + RH_EH_FIRST_FRAME = 1, + RH_EH_FIRST_RETHROW_FRAME = 2, + } + + private enum RhEHClauseKind + { + RH_EH_CLAUSE_TYPED = 0, + RH_EH_CLAUSE_FAULT = 1, + RH_EH_CLAUSE_FILTER = 2, + RH_EH_CLAUSE_UNUSED = 3, + } + + internal struct MethodRegionInfo + { + } + + internal struct ExInfo + { + } + + internal struct PAL_LIMITED_CONTEXT + { + } + + [StackTraceHidden] + [RuntimeExport("RhExceptionHandling_FailedAllocation")] + public static void FailedAllocation(MethodTable* pEEType, bool fIsOverflow) + { + ExceptionIDs exID = fIsOverflow ? ExceptionIDs.Overflow : ExceptionIDs.OutOfMemory; + + // Throw the out of memory exception defined by the classlib, using the input MethodTable* + // to find the correct classlib. + + throw pEEType->GetClasslibException(exID); + } + + private static bool ShouldTypedClauseCatchThisException(object exception, MethodTable* pClauseType) + { + return TypeCast.IsInstanceOfException(pClauseType, exception); + } + + private static void OnFirstChanceExceptionViaClassLib(object exception) + { + IntPtr pOnFirstChanceFunction = + (IntPtr)InternalCalls.RhpGetClasslibFunctionFromEEType(exception.GetMethodTable(), ClassLibFunctionId.OnFirstChance); + + if (pOnFirstChanceFunction == IntPtr.Zero) + { + return; + } + + try + { + ((delegate*)pOnFirstChanceFunction)(exception); + } + catch when (true) + { + // disallow all exceptions leaking out of callbacks + } + } + + private static void OnUnhandledExceptionViaClassLib(object exception) + { + IntPtr pOnUnhandledExceptionFunction = + (IntPtr)InternalCalls.RhpGetClasslibFunctionFromEEType(exception.GetMethodTable(), ClassLibFunctionId.OnUnhandledException); + + if (pOnUnhandledExceptionFunction == IntPtr.Zero) + { + return; + } + + try + { + ((delegate*)pOnUnhandledExceptionFunction)(exception); + } + catch when (true) + { + // disallow all exceptions leaking out of callbacks + } + } + +#pragma warning disable IDE0060 + internal static void FallbackFailFast(RhFailFastReason reason, object? unhandledException) + { + InternalCalls.RhpFallbackFailFast(); + } +#pragma warning restore IDE0060 + } } diff --git a/src/coreclr/nativeaot/Runtime/wasm/ExceptionHandling/ExceptionHandling.cpp b/src/coreclr/nativeaot/Runtime/wasm/ExceptionHandling/ExceptionHandling.cpp index 8c71e24210e7..5f16b68e02f9 100644 --- a/src/coreclr/nativeaot/Runtime/wasm/ExceptionHandling/ExceptionHandling.cpp +++ b/src/coreclr/nativeaot/Runtime/wasm/ExceptionHandling/ExceptionHandling.cpp @@ -48,8 +48,3 @@ FCIMPL0(void*, RhpGetLastPreciseVirtualUnwindFrame) return static_cast(pShadowStack) - sizeof(void*); } FCIMPLEND - -// We do not use these helpers. TODO-LLVM: exclude them from the WASM build. -FCIMPL4(void*, RhpCallCatchFunclet, void*, void*, void*, void*) { abort(); } FCIMPLEND -FCIMPL3(bool, RhpCallFilterFunclet, void*, void*, void*) { abort(); } FCIMPLEND -FCIMPL2(void, RhpCallFinallyFunclet, void*, void*) { abort(); } FCIMPLEND 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 7f09dfcc7608..afd176a315c0 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 @@ -588,9 +588,12 @@ Runtime.Base\src\System\Runtime\MethodTable.Runtime.cs - + Runtime.Base\src\System\Runtime\ExceptionHandling.cs + + Runtime.Base\src\System\Runtime\ExceptionHandling.wasm.cs + Runtime.Base\src\System\Runtime\InternalCalls.cs @@ -612,9 +615,6 @@ Common\TransitionBlock.cs - - Runtime.Base\src\System\Runtime\ExceptionHandling.wasm.cs - diff --git a/src/tests/nativeaot/Directory.Build.props b/src/tests/nativeaot/Directory.Build.props index 5c834a4948b6..30bcb1965964 100644 --- a/src/tests/nativeaot/Directory.Build.props +++ b/src/tests/nativeaot/Directory.Build.props @@ -15,4 +15,10 @@ $(DefineConstants);CODEGEN_WASM $(DefineConstants);CODEGEN_WASI + + + + + + diff --git a/src/tests/nativeaot/SmokeTests/HelloWasm/wasmjit-diff.ps1 b/src/tests/nativeaot/SmokeTests/HelloWasm/wasmjit-diff.ps1 index 5b7913e4f6f4..4b5750879d53 100644 --- a/src/tests/nativeaot/SmokeTests/HelloWasm/wasmjit-diff.ps1 +++ b/src/tests/nativeaot/SmokeTests/HelloWasm/wasmjit-diff.ps1 @@ -496,10 +496,6 @@ if ($Analyze -or $Summary) $RegressionCount = 0 $ImprovementCount = 0 - $HaveRegressionDiffs = $false - $HaveImprovementDiffs = $false - $HaveBaseOnlyMethods = $false - $HaveDiffOnlyMethods = $false $AverageRelativeCodeSizeDelta = 0.0 foreach ($Diff in $Diffs) { @@ -517,24 +513,13 @@ if ($Analyze -or $Summary) # Just skip them for now. if ($Diff.Base.Size -eq 0) { - $HaveDiffOnlyMethods = $true continue } if ($Diff.Diff.Size -eq 0) { - $HaveBaseOnlyMethods = $true continue } - if ($IsRegression) - { - $HaveRegressionDiffs = $true - } - else - { - $HaveImprovementDiffs = $true - } - $AverageRelativeCodeSizeDelta += $Diff.CodeSizeDelta / $Diff.Base.Size } @@ -558,8 +543,13 @@ if ($Analyze -or $Summary) Write-Host " average relative diff is $($AverageRelativeCodeSizeDelta -lt 0 ? 'an improvement' : 'a regression')" Write-Host "" - function ShowRelativeDiffs($DiffsToShow, $Message, $ShowBaseOnlyMethods = $false, $ShowDiffOnlyMethods = $false) + function ShowRelativeDiffs($DiffsToShow, $Message) { + if ($DiffsToShow.Length -eq 0) + { + return + } + Write-Host $Message $DiffsShown = 0 @@ -570,42 +560,33 @@ if ($Analyze -or $Summary) break } - $IsBaseOnlyMethod = $Diff.Diff.Size -eq 0 - $IsDiffOnlyMethod = $Diff.Base.Size -eq 0 - if (($ShowBaseOnlyMethods -eq $IsBaseOnlyMethod) -and ($ShowDiffOnlyMethods -eq $IsDiffOnlyMethod)) - { - Write-Host (" {0,8} ({1,6:P} of base) : {2} - {3}" -f - $Diff.CodeSizeDelta, ($Diff.CodeSizeDelta / $Diff.Base.Size), $Diff.DiffFileName, $Diff.Name) - $DiffsShown++ - } + Write-Host(" {0,8} ({1,6:P} of base) : {2} - {3}" -f + $Diff.CodeSizeDelta, ($Diff.CodeSizeDelta / $Diff.Base.Size), $Diff.DiffFileName, $Diff.Name) + $DiffsShown++ } Write-Host "" } if ($RegressionCount -ne 0) { - $RegressionDiffs = $Diffs | sort { $_.CodeSizeDelta / $_.Base.Size } -Descending | where CodeSizeDelta -gt 0 - if ($HaveRegressionDiffs) - { - ShowRelativeDiffs $RegressionDiffs "Top method regressions (percentages):" - } - if ($HaveDiffOnlyMethods) - { - ShowRelativeDiffs $RegressionDiffs "Top methods only present in diff:" -ShowDiffOnlyMethods $true - } + $RegressionDiffs = $Diffs | where CodeSizeDelta -gt 0 + + $ActualRegressionDiffs = $RegressionDiffs | where { $_.Base.Size -ne 0 } | sort { $_.CodeSizeDelta / $_.Base.Size } -Descending + ShowRelativeDiffs $ActualRegressionDiffs "Top method regressions (percentages):" + + $DiffOnlyDiffs = $RegressionDiffs | where { $_.Base.Size -eq 0 } | sort CodeSizeDelta -Descending + ShowRelativeDiffs $DiffOnlyDiffs "Top methods only present in diff:" } if ($ImprovementCount -ne 0) { - $ImprovementDiffs = $Diffs | sort { $_.CodeSizeDelta / $_.Base.Size } | where CodeSizeDelta -lt 0 - if ($HaveImprovementDiffs) - { - ShowRelativeDiffs $ImprovementDiffs "Top method improvements (percentages):" - } - if ($HaveBaseOnlyMethods) - { - ShowRelativeDiffs $ImprovementDiffs "Top methods only present in base:" -ShowBaseOnlyMethods $true - } + $ImprovementDiffs = $Diffs | where CodeSizeDelta -lt 0 + + $ActualImprovementDiffs = $ImprovementDiffs | where { $_.Diff.Size -ne 0 } | sort { $_.CodeSizeDelta / $_.Base.Size } + ShowRelativeDiffs $ActualImprovementDiffs "Top method improvements (percentages):" + + $BaseOnlyDiffs = $ImprovementDiffs | where { $_.Diff.Size -eq 0 } | sort CodeSizeDelta + ShowRelativeDiffs $BaseOnlyDiffs "Top methods only present in base:" } Write-Host "$($Diffs.Count) total methods with Code Size differences ($ImprovementCount improved, $RegressionCount regressed)"