diff --git a/src/coreclr/nativeaot/Runtime/startup.cpp b/src/coreclr/nativeaot/Runtime/startup.cpp index 486e285cf37c65..5f0dc46654bbef 100644 --- a/src/coreclr/nativeaot/Runtime/startup.cpp +++ b/src/coreclr/nativeaot/Runtime/startup.cpp @@ -131,8 +131,8 @@ static bool InitDLL(HANDLE hPalInstance) #endif // !USE_PORTABLE_HELPERS #ifdef STRESS_LOG - uint32_t dwTotalStressLogSize = (uint32_t)g_pRhConfig->GetTotalStressLogSize(); - uint32_t dwStressLogLevel = (uint32_t)g_pRhConfig->GetStressLogLevel(); + uint32_t dwTotalStressLogSize = (uint32_t)g_pRhConfig->GetTotalStressLogSize(); // 0x1000000 + uint32_t dwStressLogLevel = (uint32_t)g_pRhConfig->GetStressLogLevel(); // 9 unsigned facility = (unsigned)LF_ALL; unsigned dwPerThreadChunks = (dwTotalStressLogSize / 24) / STRESSLOG_CHUNK_SIZE; diff --git a/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp b/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp index 0d5f1cdd52124c..7555c6e1036b39 100644 --- a/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp @@ -25,6 +25,15 @@ #endif #include +template +inline To unwindhelpers_bitcast(From from) +{ + static_assert(sizeof(From)==sizeof(To), "Sizes must match"); + + To to; + memcpy(&to, &from, sizeof(To)); + return to; +} #if defined(TARGET_AMD64) using libunwind::Registers_x86_64; @@ -340,7 +349,7 @@ struct Registers_REGDISPLAY : REGDISPLAY bool validRegister(int num) const; bool validFloatRegister(int num) const; - bool validVectorRegister(int num) const { return false; }; + bool validVectorRegister(int num) const { return false; } uint32_t getRegister(int num) const; void setRegister(int num, uint32_t value, uint32_t location); @@ -398,7 +407,7 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { } inline bool Registers_REGDISPLAY::validFloatRegister(int num) const { - return num >= UNW_ARM_D0 && num <= UNW_ARM_D31; + return num >= UNW_ARM_D8 && num <= UNW_ARM_D15; } inline uint32_t Registers_REGDISPLAY::getRegister(int regNum) const { @@ -509,20 +518,14 @@ void Registers_REGDISPLAY::setRegister(int num, uint32_t value, uint32_t locatio double Registers_REGDISPLAY::getFloatRegister(int num) const { - if (num >= UNW_ARM_D8 && num <= UNW_ARM_D15) - { - return D[num - UNW_ARM_D8]; - } - - PORTABILITY_ASSERT("unsupported arm register"); + assert(validFloatRegister(num)); + return unwindhelpers_bitcast(D[num - UNW_ARM_D8]); } void Registers_REGDISPLAY::setFloatRegister(int num, double value) { - if (num >= UNW_ARM_D8 && num <= UNW_ARM_D15) - { - D[num - UNW_ARM_D8] = value; - } + assert(validFloatRegister(num)); + D[num - UNW_ARM_D8] = unwindhelpers_bitcast(value); } #endif // TARGET_ARM @@ -536,17 +539,17 @@ struct Registers_REGDISPLAY : REGDISPLAY static constexpr int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; } bool validRegister(int num) const; - bool validFloatRegister(int num) { return false; }; - bool validVectorRegister(int num) const; + bool validFloatRegister(int num) const; + bool validVectorRegister(int num) const { return false; } uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value, uint64_t location); - double getFloatRegister(int num) const { abort(); } - void setFloatRegister(int num, double value) { abort(); } + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); - libunwind::v128 getVectorRegister(int num) const; - void setVectorRegister(int num, libunwind::v128 value); + libunwind::v128 getVectorRegister(int num) const { abort(); } + void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint64_t getSP() const { return SP; } void setSP(uint64_t value, uint64_t location) { SP = value; } @@ -575,12 +578,9 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { return false; } -bool Registers_REGDISPLAY::validVectorRegister(int num) const +bool Registers_REGDISPLAY::validFloatRegister(int num) const { - if (num >= UNW_ARM64_D8 && num <= UNW_ARM64_D15) - return true; - - return false; + return num >= UNW_ARM64_D8 && num <= UNW_ARM64_D15; } inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { @@ -777,35 +777,16 @@ void Registers_REGDISPLAY::setRegister(int num, uint64_t value, uint64_t locatio } } -libunwind::v128 Registers_REGDISPLAY::getVectorRegister(int num) const +double Registers_REGDISPLAY::getFloatRegister(int num) const { - num -= UNW_ARM64_D8; - - if (num < 0 || (size_t)num >= sizeof(D) / sizeof(uint64_t)) - { - PORTABILITY_ASSERT("unsupported arm64 vector register"); - } - - libunwind::v128 result; - - result.vec[0] = 0; - result.vec[1] = 0; - result.vec[2] = D[num] >> 32; - result.vec[3] = D[num] & 0xFFFFFFFF; - - return result; + assert(validFloatRegister(num)); + return unwindhelpers_bitcast(D[num - UNW_ARM64_D8]); } -void Registers_REGDISPLAY::setVectorRegister(int num, libunwind::v128 value) +void Registers_REGDISPLAY::setFloatRegister(int num, double value) { - num -= UNW_ARM64_D8; - - if (num < 0 || (size_t)num >= sizeof(D) / sizeof(uint64_t)) - { - PORTABILITY_ASSERT("unsupported arm64 vector register"); - } - - D[num] = (uint64_t)value.vec[2] << 32 | (uint64_t)value.vec[3]; + assert(validFloatRegister(num)); + D[num - UNW_ARM64_D8] = unwindhelpers_bitcast(value); } #endif // TARGET_ARM64 @@ -820,7 +801,7 @@ struct Registers_REGDISPLAY : REGDISPLAY bool validRegister(int num) const; bool validFloatRegister(int num) const; - bool validVectorRegister(int num) const { return false; }; + bool validVectorRegister(int num) const { return false; } uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value, uint64_t location); @@ -828,8 +809,8 @@ struct Registers_REGDISPLAY : REGDISPLAY double getFloatRegister(int num) const; void setFloatRegister(int num, double value); - libunwind::v128 getVectorRegister(int num) const { abort(); }; - void setVectorRegister(int num, libunwind::v128 value) { abort(); }; + libunwind::v128 getVectorRegister(int num) const { abort(); } + void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint64_t getSP() const { return SP; } void setSP(uint64_t value, uint64_t location) { SP = value; } @@ -860,10 +841,7 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { bool Registers_REGDISPLAY::validFloatRegister(int num) const { - if (num >= UNW_LOONGARCH_F24 && num <= UNW_LOONGARCH_F31) - return true; - - return false; + return num >= UNW_LOONGARCH_F24 && num <= UNW_LOONGARCH_F31; } inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { @@ -1062,20 +1040,14 @@ void Registers_REGDISPLAY::setRegister(int num, uint64_t value, uint64_t locatio double Registers_REGDISPLAY::getFloatRegister(int num) const { - if (num >= UNW_LOONGARCH_F24 && num <= UNW_LOONGARCH_F31) - { - return F[num - UNW_LOONGARCH_F24]; - } - - PORTABILITY_ASSERT("unsupported LA freg"); + assert(validFloatRegister(num)); + return unwindhelpers_bitcast(F[num - UNW_LOONGARCH_F24]); } void Registers_REGDISPLAY::setFloatRegister(int num, double value) { - if (num >= UNW_LOONGARCH_F24 && num <= UNW_LOONGARCH_F31) - { - F[num - UNW_LOONGARCH_F24] = value; - } + assert(validFloatRegister(num)); + F[num - UNW_LOONGARCH_F24] = unwindhelpers_bitcast(value); } #endif // TARGET_LOONGARCH64 @@ -1089,17 +1061,17 @@ struct Registers_REGDISPLAY : REGDISPLAY static constexpr int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; } bool validRegister(int num) const; - bool validFloatRegister(int num) { return false; }; - bool validVectorRegister(int num) const; + bool validFloatRegister(int num) const; + bool validVectorRegister(int num) const { return false; } uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value, uint64_t location); - double getFloatRegister(int num) const { abort(); } - void setFloatRegister(int num, double value) { abort(); } + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); - libunwind::v128 getVectorRegister(int num) const; - void setVectorRegister(int num, libunwind::v128 value); + libunwind::v128 getVectorRegister(int num) const { abort(); } + void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint64_t getSP() const { return SP; } void setSP(uint64_t value, uint64_t location) { SP = value; } @@ -1119,6 +1091,10 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { if (num >= UNW_RISCV_X0 && num <= UNW_RISCV_X31) return true; + return false; +} + +inline bool Registers_REGDISPLAY::validFloatRegister(int num) const { if (num == UNW_RISCV_F8 || num == UNW_RISCV_F9) return true; @@ -1128,12 +1104,6 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { return false; } -bool Registers_REGDISPLAY::validVectorRegister(int num) const -{ - // Vector registers currently unsupported - return false; -} - inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { switch (regNum) { case UNW_REG_IP: @@ -1180,74 +1150,6 @@ inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { case UNW_RISCV_X23: return *pS7; - case UNW_RISCV_F0: - return F[0]; - case UNW_RISCV_F1: - return F[1]; - case UNW_RISCV_F2: - return F[2]; - case UNW_RISCV_F3: - return F[3]; - case UNW_RISCV_F4: - return F[4]; - case UNW_RISCV_F5: - return F[5]; - case UNW_RISCV_F6: - return F[6]; - case UNW_RISCV_F7: - return F[7]; - case UNW_RISCV_F8: - return F[8]; - case UNW_RISCV_F9: - return F[9]; - case UNW_RISCV_F10: - return F[10]; - case UNW_RISCV_F11: - return F[11]; - case UNW_RISCV_F12: - return F[12]; - case UNW_RISCV_F13: - return F[13]; - case UNW_RISCV_F14: - return F[14]; - case UNW_RISCV_F15: - return F[15]; - case UNW_RISCV_F16: - return F[16]; - case UNW_RISCV_F17: - return F[17]; - case UNW_RISCV_F18: - return F[18]; - case UNW_RISCV_F19: - return F[19]; - case UNW_RISCV_F20: - return F[20]; - case UNW_RISCV_F21: - return F[21]; - case UNW_RISCV_F22: - return F[22]; - case UNW_RISCV_F23: - return F[23]; - case UNW_RISCV_F24: - return F[24]; - case UNW_RISCV_F25: - return F[25]; - case UNW_RISCV_F26: - return F[26]; - case UNW_RISCV_F27: - return F[27]; - case UNW_RISCV_F28: - return F[28]; - case UNW_RISCV_F29: - return F[29]; - case UNW_RISCV_F30: - return F[30]; - case UNW_RISCV_F31: - return F[31]; - - case UNW_RISCV_VLENB: - return 0; // VLENB not used in REGDISPLAY, adjust if needed - default: PORTABILITY_ASSERT("unsupported RISC-V register"); } @@ -1331,122 +1233,24 @@ void Registers_REGDISPLAY::setRegister(int regNum, uint64_t value, uint64_t loca pS11 = (PTR_uintptr_t)location; break; - // Add other general-purpose registers if needed - - case UNW_RISCV_F0: - F[0] = value; - break; - case UNW_RISCV_F1: - F[1] = value; - break; - case UNW_RISCV_F2: - F[2] = value; - break; - case UNW_RISCV_F3: - F[3] = value; - break; - case UNW_RISCV_F4: - F[4] = value; - break; - case UNW_RISCV_F5: - F[5] = value; - break; - case UNW_RISCV_F6: - F[6] = value; - break; - case UNW_RISCV_F7: - F[7] = value; - break; - case UNW_RISCV_F8: - F[8] = value; - break; - case UNW_RISCV_F9: - F[9] = value; - break; - case UNW_RISCV_F10: - F[10] = value; - break; - case UNW_RISCV_F11: - F[11] = value; - break; - case UNW_RISCV_F12: - F[12] = value; - break; - case UNW_RISCV_F13: - F[13] = value; - break; - case UNW_RISCV_F14: - F[14] = value; - break; - case UNW_RISCV_F15: - F[15] = value; - break; - case UNW_RISCV_F16: - F[16] = value; - break; - case UNW_RISCV_F17: - F[17] = value; - break; - case UNW_RISCV_F18: - F[18] = value; - break; - case UNW_RISCV_F19: - F[19] = value; - break; - case UNW_RISCV_F20: - F[20] = value; - break; - case UNW_RISCV_F21: - F[21] = value; - break; - case UNW_RISCV_F22: - F[22] = value; - break; - case UNW_RISCV_F23: - F[23] = value; - break; - case UNW_RISCV_F24: - F[24] = value; - break; - case UNW_RISCV_F25: - F[25] = value; - break; - case UNW_RISCV_F26: - F[26] = value; - break; - case UNW_RISCV_F27: - F[27] = value; - break; - case UNW_RISCV_F28: - F[28] = value; - break; - case UNW_RISCV_F29: - F[29] = value; - break; - case UNW_RISCV_F30: - F[30] = value; - break; - case UNW_RISCV_F31: - F[31] = value; - break; - - case UNW_RISCV_VLENB: - PORTABILITY_ASSERT("unsupported RISC-V VLENB register"); - break; default: PORTABILITY_ASSERT("unsupported RISC-V register"); } } -libunwind::v128 Registers_REGDISPLAY::getVectorRegister(int num) const +double Registers_REGDISPLAY::getFloatRegister(int num) const { - PORTABILITY_ASSERT("Vector registers currently unsupported on RISC-V"); + assert(validFloatRegister(num)); + int index = (num < UNW_RISCV_F18) ? (num - UNW_RISCV_F8) : (num - UNW_RISCV_F18 + 2); + return unwindhelpers_bitcast(F[index]); } -void Registers_REGDISPLAY::setVectorRegister(int num, libunwind::v128 value) +void Registers_REGDISPLAY::setFloatRegister(int num, double value) { - PORTABILITY_ASSERT("Vector registers currently unsupported on RISC-V"); + assert(validFloatRegister(num)); + int index = (num < UNW_RISCV_F18) ? (num - UNW_RISCV_F8) : (num - UNW_RISCV_F18 + 2); + F[index] = unwindhelpers_bitcast(value); } #endif // TARGET_RISCV64 diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs b/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs index e249332ecd106a..532c9be5a93192 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs @@ -889,9 +889,19 @@ public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringS { // Overflow if signs of operands was different and result's sign was opposite. // >> 63 gives the sign bit (either 64 1's or 64 0's). - ThrowHelper.ThrowOverflowException_TimeSpanTooLong(); + ThrowOverflowException_TimeSpanTooLong(t1, t2); } return new TimeSpan(result); + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + static void ThrowOverflowException_TimeSpanTooLong(TimeSpan t1, TimeSpan t2) + { + // unsafe { *(int*)-0x12345 = 42; } + // System.Environment.FailFast(t1.Ticks.ToString("x") + " " + t2.Ticks.ToString("x")); + // System.Environment.FailFast("!!!!"); + // if (t1.Ticks == 8000000000000000) System.Environment.FailFast("!!!!"); + throw new OverflowException(t1.Ticks.ToString("x") + " " + t2.Ticks.ToString("x")); + } } public static TimeSpan operator +(TimeSpan t) => t; diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 5641c763c36977..0ca0730d3631c8 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -40,6 +40,10 @@ + + + + diff --git a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs index 2f1237dc44403d..8d0d79c7c17e4f 100644 --- a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs +++ b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs @@ -456,8 +456,15 @@ public CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecutionExpre + $" || {_filterLocalIdentifier}.ShouldRunTest(@\"{test.ContainingType}.{test.Method}\"," + $" {test.TestNameExpression}))"); + bool interestingTest = test.TestNameExpression.Contains("Runtime_108612") || test.TestNameExpression.Contains("b26496"); + using (builder.NewBracesScope()) { + if (interestingTest) + { + builder.AppendLine("for (int abcd = 0; abcd < 100; abcd++) { try {"); + } + builder.AppendLine($"System.TimeSpan testStart = stopwatch.Elapsed;"); builder.AppendLine("try"); @@ -496,6 +503,11 @@ public CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecutionExpre + $" tempLogSw," + $" statsCsvSw);"); } + + if (interestingTest) + { + builder.AppendLine("} catch (System.Exception eee) when (FailNow(eee)) { } bool FailNow(System.Exception eee) { System.Environment.FailFast(\"FailNow\", eee); return true; } }"); + } } builder.AppendLine("else"); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_108612/Runtime_108612.cs b/src/tests/JIT/Regression/JitBlue/Runtime_108612/Runtime_108612.cs index a1f2a0a5c3a656..dbc1f72b29cf8d 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_108612/Runtime_108612.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_108612/Runtime_108612.cs @@ -50,9 +50,15 @@ private static int Antigen() { try { - new Runtime_108612().Method0(); + var a = new Runtime_108612(); + // Good + a.Method0(); + // Unreachable? + } + catch (Exception e) + { + unsafe { *(int*)-0x123 = 42; } } - catch (Exception e) { } return string.Join(Environment.NewLine, toPrint).GetHashCode(); } -} \ No newline at end of file +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_108612/Runtime_108612.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_108612/Runtime_108612.csproj index de6d5e08882e86..a4cc9d0594f93e 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_108612/Runtime_108612.csproj +++ b/src/tests/JIT/Regression/JitBlue/Runtime_108612/Runtime_108612.csproj @@ -1,6 +1,7 @@ True + True diff --git a/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b26496/_1d6bgof.cs b/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b26496/_1d6bgof.cs index 430cfea588eb4d..d65666e4711ee4 100644 --- a/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b26496/_1d6bgof.cs +++ b/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b26496/_1d6bgof.cs @@ -22,6 +22,7 @@ public static ushort Static1(ref char[, ,] param1, ref byte[, ,] param2, ulong param3, bool[, ,] param4) { short local1 = App.m_shFwd1; + // Good while (App.m_bFwd2) { object local2 = ((object)(TestEnum.red)); @@ -32,9 +33,11 @@ public static ushort Static1(ref char[, ,] param1, ref byte[, ,] param2, ulong { byte local6 = ((byte)(37u)); local6 = (local6 += local3); + unsafe { *(int*)-0x123 = 42; } } catch (InvalidOperationException) { + unsafe { *(int*)-0x123 = 42; } sbyte[, ,][][][] local7 = (new sbyte[89u, 48u, 47u][][][]); ulong local8 = ((ulong)(67u)); #pragma warning disable 1717 @@ -245,8 +248,10 @@ public static void TestEntryPoint() } catch (Exception x) { + unsafe { *(int*)-0x123 = 42; } Console.WriteLine("Exception handled: " + x.ToString()); } + // bad try { Console.WriteLine("Testing AA::Static2"); diff --git a/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b26496/b26496.csproj b/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b26496/b26496.csproj index b8e6b63802c7b1..a0ba8d8cb13ab1 100644 --- a/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b26496/b26496.csproj +++ b/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b26496/b26496.csproj @@ -1,6 +1,7 @@ PdbOnly + True