Skip to content

Commit c02fb4d

Browse files
committed
Change stack size
- Change stack size to 4MB on 64-bit desktop - Add tests to check stack size
1 parent f48a99e commit c02fb4d

File tree

10 files changed

+133
-13
lines changed

10 files changed

+133
-13
lines changed

eng/native/configurecompiler.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ if (MSVC)
102102
if (CLR_CMAKE_ENABLE_SANITIZERS)
103103
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:0x800000")
104104
else()
105-
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:0x180000")
105+
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:0x400000")
106106
endif()
107107

108108
if(EXISTS ${CLR_SOURCELINK_FILE_PATH})

src/coreclr/pal/src/init/pal.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,20 @@ InitializeDefaultStackSize()
288288
}
289289
}
290290

291+
#ifdef HOST_OSX
292+
// Match Windows stack size
293+
if (g_defaultStackSize == 0)
294+
{
295+
g_defaultStackSize = 4096 * 1024;
296+
}
297+
#endif
298+
291299
#ifdef ENSURE_PRIMARY_STACK_SIZE
292300
if (g_defaultStackSize == 0)
293301
{
294302
// Set the default minimum stack size for MUSL to the same value as we
295303
// use on Windows.
296-
g_defaultStackSize = 1536 * 1024;
304+
g_defaultStackSize = 4096 * 1024;
297305
}
298306
#endif // ENSURE_PRIMARY_STACK_SIZE
299307
}

src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3400,7 +3400,7 @@ internal PEHeader() { }
34003400
}
34013401
public sealed partial class PEHeaderBuilder
34023402
{
3403-
public PEHeaderBuilder(System.Reflection.PortableExecutable.Machine machine = System.Reflection.PortableExecutable.Machine.Unknown, int sectionAlignment = 8192, int fileAlignment = 512, ulong imageBase = (ulong)4194304, byte majorLinkerVersion = (byte)48, byte minorLinkerVersion = (byte)0, ushort majorOperatingSystemVersion = (ushort)4, ushort minorOperatingSystemVersion = (ushort)0, ushort majorImageVersion = (ushort)0, ushort minorImageVersion = (ushort)0, ushort majorSubsystemVersion = (ushort)4, ushort minorSubsystemVersion = (ushort)0, System.Reflection.PortableExecutable.Subsystem subsystem = System.Reflection.PortableExecutable.Subsystem.WindowsCui, System.Reflection.PortableExecutable.DllCharacteristics dllCharacteristics = System.Reflection.PortableExecutable.DllCharacteristics.DynamicBase | System.Reflection.PortableExecutable.DllCharacteristics.NoSeh | System.Reflection.PortableExecutable.DllCharacteristics.NxCompatible | System.Reflection.PortableExecutable.DllCharacteristics.TerminalServerAware, System.Reflection.PortableExecutable.Characteristics imageCharacteristics = System.Reflection.PortableExecutable.Characteristics.Dll, ulong sizeOfStackReserve = (ulong)1048576, ulong sizeOfStackCommit = (ulong)4096, ulong sizeOfHeapReserve = (ulong)1048576, ulong sizeOfHeapCommit = (ulong)4096) { }
3403+
public PEHeaderBuilder(System.Reflection.PortableExecutable.Machine machine = System.Reflection.PortableExecutable.Machine.Unknown, int sectionAlignment = 8192, int fileAlignment = 512, ulong imageBase = (ulong)4194304, byte majorLinkerVersion = (byte)48, byte minorLinkerVersion = (byte)0, ushort majorOperatingSystemVersion = (ushort)4, ushort minorOperatingSystemVersion = (ushort)0, ushort majorImageVersion = (ushort)0, ushort minorImageVersion = (ushort)0, ushort majorSubsystemVersion = (ushort)4, ushort minorSubsystemVersion = (ushort)0, System.Reflection.PortableExecutable.Subsystem subsystem = System.Reflection.PortableExecutable.Subsystem.WindowsCui, System.Reflection.PortableExecutable.DllCharacteristics dllCharacteristics = System.Reflection.PortableExecutable.DllCharacteristics.DynamicBase | System.Reflection.PortableExecutable.DllCharacteristics.NoSeh | System.Reflection.PortableExecutable.DllCharacteristics.NxCompatible | System.Reflection.PortableExecutable.DllCharacteristics.TerminalServerAware, System.Reflection.PortableExecutable.Characteristics imageCharacteristics = System.Reflection.PortableExecutable.Characteristics.Dll, ulong sizeOfStackReserve = (ulong)0, ulong sizeOfStackCommit = (ulong)0, ulong sizeOfHeapReserve = (ulong)0, ulong sizeOfHeapCommit = (ulong)0) { }
34043404
public System.Reflection.PortableExecutable.DllCharacteristics DllCharacteristics { get { throw null; } }
34053405
public int FileAlignment { get { throw null; } }
34063406
public ulong ImageBase { get { throw null; } }

src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEHeaderBuilder.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ public PEHeaderBuilder(
5959
Subsystem subsystem = Subsystem.WindowsCui,
6060
DllCharacteristics dllCharacteristics = DllCharacteristics.DynamicBase | DllCharacteristics.NxCompatible | DllCharacteristics.NoSeh | DllCharacteristics.TerminalServerAware,
6161
Characteristics imageCharacteristics = Characteristics.Dll,
62-
ulong sizeOfStackReserve = 0x00100000,
63-
ulong sizeOfStackCommit = 0x1000,
64-
ulong sizeOfHeapReserve = 0x00100000,
65-
ulong sizeOfHeapCommit = 0x1000)
62+
ulong sizeOfStackReserve = 0,
63+
ulong sizeOfStackCommit = 0,
64+
ulong sizeOfHeapReserve = 0,
65+
ulong sizeOfHeapCommit = 0)
6666
{
6767
if (fileAlignment < 512 || fileAlignment > 64 * 1024 || BitArithmetic.CountBits(fileAlignment) != 1)
6868
{
@@ -89,10 +89,10 @@ public PEHeaderBuilder(
8989
Subsystem = subsystem;
9090
DllCharacteristics = dllCharacteristics;
9191
ImageCharacteristics = imageCharacteristics;
92-
SizeOfStackReserve = sizeOfStackReserve;
93-
SizeOfStackCommit = sizeOfStackCommit;
94-
SizeOfHeapReserve = sizeOfHeapReserve;
95-
SizeOfHeapCommit = sizeOfHeapCommit;
92+
SizeOfStackReserve = sizeOfStackReserve == 0 ? (Is32Bit ? 0x1000u : 0x4000u) : sizeOfStackReserve;
93+
SizeOfStackCommit = sizeOfStackCommit == 0 ? (Is32Bit ? 0x1000000u : 0x4000000u) : sizeOfStackCommit;
94+
SizeOfHeapReserve = sizeOfHeapReserve == 0 ? 0x100000u : sizeOfHeapReserve;
95+
SizeOfHeapCommit = sizeOfHeapCommit == 0 ? (Is32Bit ? 0x1000u : 0x2000u) : sizeOfHeapCommit;
9696
}
9797

9898
public static PEHeaderBuilder CreateExecutableHeader()

src/native/libs/System.Native/pal_threading.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,14 @@ int32_t SystemNative_CreateThread(uintptr_t stackSize, void *(*startAddress)(voi
233233
error = pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
234234
assert(error == 0);
235235

236+
#ifdef HOST_OSX
237+
// Match Windows stack size
238+
if (stackSize == 0)
239+
{
240+
stackSize = 4096 * 1024;
241+
}
242+
#endif
243+
236244
if (stackSize > 0)
237245
{
238246
if (stackSize < (uintptr_t)PTHREAD_STACK_MIN)

src/tests/Exceptions/ForeignThread/ForeignThreadExceptionsNative.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ extern "C" DLL_EXPORT void InvokeCallbackOnNewThread(PFNACTION1 callback)
4949
int st = pthread_attr_init(&attr);
5050
AbortIfFail(st);
5151

52-
// set stack size to 1.5MB
53-
st = pthread_attr_setstacksize(&attr, 0x180000);
52+
// set stack size to 4.0MB
53+
st = pthread_attr_setstacksize(&attr, 0x400000);
5454
AbortIfFail(st);
5555

5656
pthread_t t;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Threading;
6+
using System.Runtime.CompilerServices;
7+
8+
class Program
9+
{
10+
[SkipLocalsInit]
11+
static int Main()
12+
{
13+
//determine the expected available stack size (4MB or 1MB), minus a little bit (384kB) for overhead.
14+
var expectedSize = (IntPtr.Size == 8 ? 0x4_00000 : 0x1_00000) - 0x60000;
15+
16+
//allocate 4MB, minus a little bit (512kB) for overhead
17+
Span<byte> bytes = stackalloc byte[expectedSize];
18+
Consume(bytes);
19+
Console.WriteLine("Main thread succeeded.");
20+
21+
//repeat on a secondary thread
22+
Thread t = new Thread([SkipLocalsInit] () =>
23+
{
24+
Span<byte> bytes = stackalloc byte[expectedSize];
25+
Consume(bytes);
26+
});
27+
t.Start();
28+
t.Join();
29+
Console.WriteLine("Secondary thread succeeded.");
30+
31+
//success
32+
return 100;
33+
}
34+
35+
[MethodImpl(MethodImplOptions.NoInlining)]
36+
static void Consume(Span<byte> bytes)
37+
{
38+
}
39+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
5+
<CLRTestTargetUnsupported>true</CLRTestTargetUnsupported>
6+
<CLRTestTargetUnsupported Condition="'$(TargetsWindows)' == 'true' OR ('$(TargetsUnix)' == 'true' AND '$(TargetsMobile)' != 'true')">false</CLRTestTargetUnsupported>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<Compile Include="test87879.cs" />
10+
</ItemGroup>
11+
</Project>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Threading;
6+
using System.Runtime.CompilerServices;
7+
8+
namespace DesktopStackSize
9+
{
10+
class Program
11+
{
12+
[SkipLocalsInit]
13+
static int Main()
14+
{
15+
//determine the expected available stack size (4MB or 1MB), minus a little bit (384kB) for overhead.
16+
var expectedSize = (IntPtr.Size == 8 ? 0x4_00000 : 0x1_00000) - 0x60000;
17+
18+
//allocate 4MB, minus a little bit (512kB) for overhead
19+
Span<byte> bytes = stackalloc byte[expectedSize];
20+
Consume(bytes);
21+
Console.WriteLine("Main thread succeeded.");
22+
23+
//repeat on a secondary thread
24+
Thread t = new Thread([SkipLocalsInit] () =>
25+
{
26+
Span<byte> bytes = stackalloc byte[expectedSize];
27+
Consume(bytes);
28+
});
29+
t.Start();
30+
t.Join();
31+
Console.WriteLine("Secondary thread succeeded.");
32+
33+
//success
34+
return 100;
35+
}
36+
37+
[MethodImpl(MethodImplOptions.NoInlining)]
38+
static void Consume(Span<byte> bytes)
39+
{
40+
}
41+
}
42+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
5+
<CLRTestTargetUnsupported>true</CLRTestTargetUnsupported>
6+
<CLRTestTargetUnsupported Condition="'$(TargetsWindows)' == 'true' OR ('$(TargetsUnix)' == 'true' AND '$(TargetsMobile)' != 'true')">false</CLRTestTargetUnsupported>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<Compile Include="DesktopStackSize.cs" />
11+
</ItemGroup>
12+
</Project>

0 commit comments

Comments
 (0)