Skip to content

Commit

Permalink
Opt, 使用Tls重写ptd_downlevel,提高性能
Browse files Browse the repository at this point in the history
  • Loading branch information
mingkuang-Chuyu committed May 25, 2024
1 parent 73d17a9 commit 07994ed
Show file tree
Hide file tree
Showing 15 changed files with 79 additions and 130 deletions.
4 changes: 1 addition & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
<EnableEnhancedInstructionSet Condition="'$(Platform)' == 'Win32'">NoExtensions</EnableEnhancedInstructionSet>
<DisableSpecificWarnings>4200;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<!--最低支持目标为XP 2003时,则还需要禁用threadSafeInit-->
<AdditionalOptions Condition="'$(WindowsTargetPlatformMinVersionBuild)' &gt;= '6000'">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
<!--禁用FH4,因为早期版本 2015 2017都是没有这个功能的,实际上,微软自己也是禁用的。-->
<AdditionalOptions Condition="'$(Platform)'=='x64'">/d2FH4- %(AdditionalOptions)</AdditionalOptions>
<!--避免使用tlsGuards,因为VC-LTL能确保不会使用那些动态的。此外避免高版本依赖-->
Expand All @@ -33,4 +31,4 @@
<DirectoryBuildPropsPath>$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))</DirectoryBuildPropsPath>
</PropertyGroup>
<Import Project="$(DirectoryBuildPropsPath)" Condition="'$(DirectoryBuildPropsPath)' != ''"/>
</Project>
</Project>
8 changes: 2 additions & 6 deletions Nuget/VC-LTL.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,10 @@
<dependencies>
<group targetFramework="native">
<dependency id="YY.NuGet.Import.Helper" version="1.0.0.4" />
<dependency id="YY-Thunks" version="[1.0.10-Beta8,)"/>
</group>
<group targetFramework="net8.0-windows7.0">
<!--
YY-Thunks 1.0.10-Beta2开始才解决Windows XP、Windows Vista、Windows 7的API缺失问题
YY-Thunks 1.0.10-Beta3开始直接支持在.NET Native AOT使用
YY-Thunks 1.0.10-Beta4开始解决兼容XP时PE头部的最小系统版本不更新问题
-->
<dependency id="YY-Thunks" version="[1.0.10-Beta4,)"/>
<dependency id="YY-Thunks" version="[1.0.10-Beta8,)"/>
</group>
</dependencies>
</metadata>
Expand Down
76 changes: 0 additions & 76 deletions Sources/crt/ptd_downlevel.cpp

This file was deleted.

50 changes: 40 additions & 10 deletions Sources/crt/ptd_downlevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,60 @@

struct ptd_downlevel
{
//所需线程ID
unsigned dwThreadId;
uintptr_t bInit;
#if WindowsTargetPlatformMinVersion < WindowsTargetPlatformWindows10_10240
void(__cdecl* _thread_local_iph)(
wchar_t const*,
wchar_t const*,
wchar_t const*,
unsigned int,
uintptr_t
);
#if defined (_M_IA64) || defined (_M_AMD64) || defined (_M_ARM64) || defined (_M_ARM)
void* _pForeignException;
#endif

#if WindowsTargetPlatformMinVersion < WindowsTargetPlatformWindowsXP
int _ProcessingThrow; /* for uncaught_exception */
#endif

#if WindowsTargetPlatformMinVersion < WindowsTargetPlatformWindows6
int _cxxReThrow;
#endif

#if defined (_M_IA64) || defined (_M_AMD64) || defined (_M_ARM64) || defined (_M_ARM) || defined _M_HYBRID
#if WindowsTargetPlatformMinVersion < WindowsTargetPlatformWindows6
uintptr_t _ImageBase;
uintptr_t _ThrowImageBase;
void* _pForeignException;
#endif
int _cxxReThrow;
#if defined _M_X64 || defined _M_ARM || defined _M_ARM64 || defined _M_HYBRID
int _CatchStateInParent;

#if WindowsTargetPlatformMinVersion < __MakeVersion(10, 0, 19041)
int _CatchStateInParent;
#endif

#endif // defined (_M_IA64) || defined (_M_AMD64) || defined (_M_ARM64) || defined (_M_ARM)

#if defined(_M_IX86)
int _ProcessingThrow; /* for uncaught_exception */

#if WindowsTargetPlatformMinVersion < WindowsTargetPlatformWindows6
void* _pFrameInfoChain;
#endif
#endif // defined(_M_IX86)
};

EXTERN_C ptd_downlevel* __fastcall __LTL_get_ptd_downlevel(BOOL bCanAlloc);
#if WindowsTargetPlatformMinVersion < __MakeVersion(10, 0, 19041)
__declspec(noinline) inline ptd_downlevel* __fastcall __LTL_get_ptd_downlevel()
{
static thread_local ptd_downlevel s_ptd_downlevel;
if (!s_ptd_downlevel.bInit)
{
s_ptd_downlevel.bInit = 1;
__if_exists(ptd_downlevel::_CatchStateInParent)
{
s_ptd_downlevel._CatchStateInParent = -2;//INVALID_CATCH_SPECIFIC_STATE
}
}

#endif
return &s_ptd_downlevel;
}
#endif
#endif // _LTL_ptd_downlevel
2 changes: 1 addition & 1 deletion Sources/crt/vcruntime/ehhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#else
#include <ptd_downlevel.h>
#define _pForeignExceptWin6 (*((EHExceptionRecord **)&(((_ptd_msvcrt_win6_shared*)RENAME_BASE_PTD(__vcrt_getptd)())->_pForeignException)))
#define _pForeignExceptdownlevel (*((EHExceptionRecord **)&(__LTL_get_ptd_downlevel(TRUE)->_pForeignException)))
#define _pForeignExceptdownlevel (*((EHExceptionRecord **)&(__LTL_get_ptd_downlevel()->_pForeignException)))
#define _pForeignExcept (__LTL_GetOsMinVersion() >= MakeMiniVersion(6, 0) ? _pForeignExceptWin6 : _pForeignExceptdownlevel)
#endif

Expand Down
2 changes: 1 addition & 1 deletion Sources/crt/vcruntime/frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ using namespace FH4;
#include <ptd_downlevel.h>

#define cxxReThrowWin6 (((_ptd_msvcrt_win6_shared*)RENAME_BASE_PTD(__vcrt_getptd)())->_cxxReThrow)
#define cxxReThrowdownlevel (__LTL_get_ptd_downlevel(TRUE)->_cxxReThrow)
#define cxxReThrowdownlevel (__LTL_get_ptd_downlevel()->_cxxReThrow)
#define cxxReThrow (__LTL_GetOsMinVersion() >= MakeMiniVersion(6,0) ? cxxReThrowWin6 : cxxReThrowdownlevel)
#endif

Expand Down
10 changes: 2 additions & 8 deletions Sources/crt/vcruntime/risctrnsctrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#else
#include <ptd_downlevel.h>
#define _ImageBaseWin6 (((_ptd_msvcrt_win6_shared*)__vcrt_getptd())->_ImageBase)
#define _ImageBasedownlevel (__LTL_get_ptd_downlevel(TRUE)->_ImageBase)
#define _ImageBasedownlevel (__LTL_get_ptd_downlevel()->_ImageBase)
#define _ImageBase (__LTL_GetOsMinVersion() >= MakeMiniVersion(6,0) ? _ImageBaseWin6 : _ImageBasedownlevel)
#endif
extern "C" uintptr_t __cdecl _GetImageBase()
Expand All @@ -60,7 +60,7 @@ extern "C" void __cdecl _SetImageBase(uintptr_t ImageBaseToRestore)
#else
#include <ptd_downlevel.h>
#define _ThrowImageBaseWin6 (((_ptd_msvcrt_win6_shared*)__vcrt_getptd())->_ThrowImageBase)
#define _ThrowImageBasedownlevel (__LTL_get_ptd_downlevel(TRUE)->_ThrowImageBase)
#define _ThrowImageBasedownlevel (__LTL_get_ptd_downlevel()->_ThrowImageBase)
#define _ThrowImageBase (__LTL_GetOsMinVersion() >= MakeMiniVersion(6,0) ? _ThrowImageBaseWin6 : _ThrowImageBasedownlevel)
#endif

Expand All @@ -76,12 +76,6 @@ extern "C" void __cdecl _SetThrowImageBase(uintptr_t NewThrowImageBase)

#endif

#if 1
#if _VCRT_BUILD_FH4 && WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6
thread_local int VC_LTL_UCRT_CatchStateInParent = INVALID_CATCH_SPECIFIC_STATE;
#endif // _VCRT_BUILD_FH4 && WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6
#endif // 1

#if _EH_RELATIVE_FUNCINFO
#if _VCRT_BUILD_FH4
//
Expand Down
8 changes: 3 additions & 5 deletions Sources/crt/vcruntime/trnsctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,12 @@ extern "C" _VCRTIMP int* __cdecl __processing_throw();
#if _VCRT_BUILD_FH4
// In the satellite build, __vcrt_getptd uses satellite's PTD
// In the non-DLL build, __vcrt_getptd uses the main PTD which was updated to have this field
#if WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6
extern thread_local int VC_LTL_UCRT_CatchStateInParent;
#define CatchStateInParent (VC_LTL_UCRT_CatchStateInParent)
#if WindowsTargetPlatformMinVersion >= __MakeVersion(10, 0, 19041)
#define CatchStateInParent (RENAME_BASE_PTD(__vcrt_getptd)()->_CatchStateInParent)
#else
#include <ptd_downlevel.h>
#define CatchStateInParent (__LTL_get_ptd_downlevel(TRUE)->_CatchStateInParent)
#define CatchStateInParent (__LTL_get_ptd_downlevel()->_CatchStateInParent)
#endif

#endif

#pragma pack(pop)
5 changes: 3 additions & 2 deletions Sources/crt/vcruntime/vcruntime_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,11 @@ typedef struct RENAME_BASE_PTD(__vcrt_ptd)
uintptr_t _ThrowImageBase;
void* _pForeignException;

//2015 没有这个
//int _CatchStateInParent; // Used to link together the catch funclet with the parent. During dispatch contains state associated
#if WindowsTargetPlatformMinVersion >= __MakeVersion(10, 0, 19041)
int _CatchStateInParent; // Used to link together the catch funclet with the parent. During dispatch contains state associated
// with catch in the parent. During unwind represents the current unwind state that is resumed to
// during collided unwind and used to look for handlers of the throwing dtor.
#endif
#elif defined _M_IX86
void* _pFrameInfoChain;
#endif
Expand Down
6 changes: 2 additions & 4 deletions Sources/ucrt/misc/invalid_parameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ static _invalid_parameter_handler __acrt_invalid_parameter_handler = nullptr;

#if WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows10_10240
#define _thread_local_iph _get_thread_local_invalid_parameter_handler()
#elif WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6
static thread_local _invalid_parameter_handler _thread_local_iph;
#else
#include <ptd_downlevel.h>
#define _thread_local_iph (__LTL_get_ptd_downlevel(TRUE)->_thread_local_iph)
#define _thread_local_iph (__LTL_get_ptd_downlevel()->_thread_local_iph)
#endif

#if defined _M_X64 && !defined _UCRT_ENCLAVE_BUILD
Expand Down Expand Up @@ -328,4 +326,4 @@ extern "C" _invalid_parameter_handler __cdecl _get_thread_local_invalid_paramete
}

_LCRT_DEFINE_IAT_SYMBOL(_get_thread_local_invalid_parameter_handler);
#endif
#endif
4 changes: 3 additions & 1 deletion config/config.props
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,10 @@
<PreprocessorDefinitions>_Build_By_LTL=1;_LTL_Core_Version=$(LTL_CoreVersion);%(PreprocessorDefinitions)</PreprocessorDefinitions>

<PreprocessorDefinitions Condition="'$(SupportWinXP)'=='true'">_ATL_XP_TARGETING=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<!--当兼容XP时,对于非 exe 的需要禁用线程安全初始化。避免XP中在DllMain中使用TLS而崩溃-->
<!--YY-Thunks 1.0.10-Beta8开始已经为Windows XP添加了完整的Tls支持,所以无需在`/Zc:threadSafeInit-`。
当兼容XP时,对于非 exe 的需要禁用线程安全初始化。避免XP中在DllMain中使用TLS而崩溃
<AdditionalOptions Condition="'$(SupportWinXP)'=='true' and '$(ConfigurationType)'!='Application' ">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
-->
</ClCompile>
<Link Condition="'$(SupportWinXP)'=='true'">
<MinimumRequiredVersion Condition=" '$(PlatformShortName)'=='x86' ">5.01</MinimumRequiredVersion>
Expand Down
8 changes: 1 addition & 7 deletions ucrtbase.msvcrt/localeconv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,8 @@ extern "C" lconv* __cdecl localeconv(void)

auto _Page = ___lc_codepage_func();

#if WindowsTargetPlatformMinVersion < WindowsTargetPlatformWindows6
//低于Vista,那么无法安全的使用 thread_local
static lconv_with_static_buffer ThreadBuffer[0x4000];

auto& Current = ThreadBuffer[(GetCurrentThreadId() >> 1) % __crt_countof(ThreadBuffer)];
#else
// 由YY-Thunks为Windows XP提供完整的thread_local支持
static thread_local lconv_with_static_buffer Current;
#endif

if (Current.decimal_point != pOrglconv->decimal_point)
{
Expand Down
4 changes: 1 addition & 3 deletions ucrtbase.msvcrt/ucrtbase.msvcrt.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -658,9 +658,6 @@
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\Sources\crt\ptd_downlevel.cpp">
<ExcludedFromBuild Condition="'$(WindowsTargetPlatformMinVersionBuild)' &gt;= '6000'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\Sources\ltl\debug_heap.cpp">
<ExcludedFromBuild Condition="'$(UseDebugLibraries)' != 'true'">true</ExcludedFromBuild>
</ClCompile>
Expand Down Expand Up @@ -1296,6 +1293,7 @@
<ClCompile Include="_file.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Sources\crt\ptd_downlevel.h" />
<ClInclude Include="msvcrt_build_type.h" />
<ClInclude Include="msvcrt_loadhelper.h" />
</ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions ucrtbase.msvcrt/ucrtbase.msvcrt.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -765,9 +765,6 @@
<ClCompile Include="..\Sources\ucrt\stdlib\rand_s.cpp">
<Filter>源文件\WinXP</Filter>
</ClCompile>
<ClCompile Include="..\Sources\crt\ptd_downlevel.cpp">
<Filter>头文件\ltl</Filter>
</ClCompile>
<ClCompile Include="..\Sources\ucrt\locale\GetStringTypeA.cpp">
<Filter>源文件\objs</Filter>
</ClCompile>
Expand Down Expand Up @@ -806,5 +803,8 @@
<ClInclude Include="msvcrt_build_type.h">
<Filter>头文件\ltl</Filter>
</ClInclude>
<ClInclude Include="..\Sources\crt\ptd_downlevel.h">
<Filter>头文件\ltl</Filter>
</ClInclude>
</ItemGroup>
</Project>
Loading

0 comments on commit 07994ed

Please sign in to comment.