summaryrefslogtreecommitdiff
path: root/src/vm/codeman.cpp
diff options
context:
space:
mode:
authorKyungwoo Lee <kyulee@microsoft.com>2016-07-20 08:50:22 -0700
committerKyungwoo Lee <kyulee@microsoft.com>2016-07-20 08:50:22 -0700
commitb37e6fc8f5cd72eaae9258df2158bb85e5ff43dc (patch)
tree86823d60dc4b835e1210a2dba5ec7116ef5601a5 /src/vm/codeman.cpp
parente9774389f13862104605a092921d4e3872524096 (diff)
downloadcoreclr-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.cpp29
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