diff options
author | Kyungwoo Lee <kyulee@microsoft.com> | 2016-07-20 08:50:22 -0700 |
---|---|---|
committer | Kyungwoo Lee <kyulee@microsoft.com> | 2016-07-20 08:50:22 -0700 |
commit | b37e6fc8f5cd72eaae9258df2158bb85e5ff43dc (patch) | |
tree | 86823d60dc4b835e1210a2dba5ec7116ef5601a5 /src/vm/codeman.cpp | |
parent | e9774389f13862104605a092921d4e3872524096 (diff) | |
download | coreclr-b37e6fc8f5cd72eaae9258df2158bb85e5ff43dc.tar.gz coreclr-b37e6fc8f5cd72eaae9258df2158bb85e5ff43dc.tar.bz2 coreclr-b37e6fc8f5cd72eaae9258df2158bb85e5ff43dc.zip |
ARM64: Enable Function Fragment
Fixes https://github.com/dotnet/coreclr/issues/6064
Fixes https://github.com/dotnet/coreclr/issues/6122
Basically this enable function fragment.
Unwind data for arm64 can express only 1MB range.
For the large function, we should split unwind data for each fragment of
function. Other than the first fragment (the host region), each fragment
has a phantom prolog starting with "end_c(0xe5)".
I confirmed that this implementation aligns with window's unwinder, and
tested with COMPlus_JitSplitFunctionSize=32 for a few test cases which
split both main and funclets.
Diffstat (limited to 'src/vm/codeman.cpp')
-rw-r--r-- | src/vm/codeman.cpp | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp index 7eea254646..9fce5b542f 100644 --- a/src/vm/codeman.cpp +++ b/src/vm/codeman.cpp @@ -858,39 +858,34 @@ BOOL IsFunctionFragment(TADDR baseAddress, PTR_RUNTIME_FUNCTION pFunctionEntry) // 1. Prolog only: The host record. Epilog Count and E bit are all 0. // 2. Prolog and some epilogs: The host record with acompannying epilog-only records // 3. Epilogs only: First unwind code is Phantom prolog (Starting with an end_c, indicating an empty prolog) - // 4. No prologs or epilogs: Epilog Count = 1 and Epilog Start Index points end_c. (as if it's case #2 with empty epilog codes) + // 4. No prologs or epilogs: First unwind code is Phantom prolog (Starting with an end_c, indicating an empty prolog) // int EpilogCount = (int)(unwindHeader >> 22) & 0x1F; int CodeWords = unwindHeader >> 27; PTR_DWORD pUnwindCodes = (PTR_DWORD)(baseAddress + pFunctionEntry->UnwindData); + // Skip header. + pUnwindCodes++; + + // Skip extended header. if ((CodeWords == 0) && (EpilogCount == 0)) - pUnwindCodes++; - BOOL Ebit = (unwindHeader >> 21) & 0x1; - if (Ebit) { - // EpilogCount is the index of the first unwind code that describes the one and only epilog - // The unwind codes immediatelly follow the unwindHeader + EpilogCount = (*pUnwindCodes) & 0xFFFF; pUnwindCodes++; } - else if (EpilogCount != 0) + + // Skip epilog scopes. + BOOL Ebit = (unwindHeader >> 21) & 0x1; + if (!Ebit && (EpilogCount != 0)) { // EpilogCount is the number of exception scopes defined right after the unwindHeader - pUnwindCodes += EpilogCount+1; + pUnwindCodes += EpilogCount; } - else - { - return FALSE; - } - - if ((*pUnwindCodes & 0xFF) == 0xE5) // Phantom prolog - return TRUE; - + return ((*pUnwindCodes & 0xFF) == 0xE5); #else PORTABILITY_ASSERT("IsFunctionFragnent - NYI on this platform"); #endif - return FALSE; } #endif // EXCEPTION_DATA_SUPPORTS_FUNCTION_FRAGMENTS |