diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2018-07-18 22:09:27 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2018-07-18 22:09:27 +0300 |
commit | 883cd734efff8152924153e5df29c19f41b24da1 (patch) | |
tree | afb2e94433fcc741b9b42a7cdd0b020197fb73e5 /src | |
parent | a394e915916c4abbff08636884124c6e82f36a8f (diff) |
Make ThreadStatics a bit more faster (#6109)
Over lunch, I realized I could have done a bit more than I've done in #6108. This squeezes out another 7% on my microbenchmark by eliminating an array range check (with the `uint` cast trick), and factoring out the slow path. Now we're definitely faster than the CLR on the microbenchmark.
Diffstat (limited to 'src')
-rw-r--r-- | src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs b/src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs index b125d8fa2..be6537858 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs @@ -4,6 +4,7 @@ using System; using System.Runtime; +using System.Runtime.CompilerServices; using Internal.Runtime.CompilerHelpers; namespace Internal.Runtime @@ -21,18 +22,26 @@ namespace Internal.Runtime internal static unsafe object GetThreadStaticBaseForType(TypeManagerSlot* pModuleData, int typeTlsIndex) { // Get the array that holds thread static memory blocks for each type in the given module - int moduleIndex = pModuleData->ModuleIndex; - object[] storage = RuntimeImports.RhGetThreadStaticStorageForModule(moduleIndex); + object[] storage = RuntimeImports.RhGetThreadStaticStorageForModule(pModuleData->ModuleIndex); // Check whether thread static storage has already been allocated for this module and type. - if ((storage != null) && (typeTlsIndex < storage.Length) && (storage[typeTlsIndex] != null)) + if ((storage != null) && ((uint)typeTlsIndex < (uint)storage.Length) && (storage[typeTlsIndex] != null)) { return storage[typeTlsIndex]; } + return GetThreadStaticBaseForTypeSlow(pModuleData, typeTlsIndex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static unsafe object GetThreadStaticBaseForTypeSlow(TypeManagerSlot* pModuleData, int typeTlsIndex) + { + // Get the array that holds thread static memory blocks for each type in the given module + object[] storage = RuntimeImports.RhGetThreadStaticStorageForModule(pModuleData->ModuleIndex); + // This the first access to the thread statics of the type corresponding to typeTlsIndex. // Make sure there is enough storage allocated to hold it. - storage = EnsureThreadStaticStorage(moduleIndex, storage, requiredSize: typeTlsIndex + 1); + storage = EnsureThreadStaticStorage(pModuleData->ModuleIndex, storage, requiredSize: typeTlsIndex + 1); // Allocate an object that will represent a memory block for all thread static fields of the type object threadStaticBase = AllocateThreadStaticStorageForType(pModuleData->TypeManager, typeTlsIndex); |