Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFilip Navara <navara@emclient.com>2022-10-01 17:12:54 +0300
committerGitHub <noreply@github.com>2022-10-01 17:12:54 +0300
commitfd9fc1d195121f4dc13143f6232f6d516a567333 (patch)
tree8ca70158a3cd6717e069224a67f1eb4a755a29bc /src
parent452fd845d131b39b5837d4513e569a540a92b359 (diff)
Improve early bail-out logic in GCInfoDecoder (#76359)
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Diffstat (limited to 'src')
-rw-r--r--src/coreclr/vm/gcinfodecoder.cpp46
1 files changed, 39 insertions, 7 deletions
diff --git a/src/coreclr/vm/gcinfodecoder.cpp b/src/coreclr/vm/gcinfodecoder.cpp
index ab87649a1eb..f69513e0559 100644
--- a/src/coreclr/vm/gcinfodecoder.cpp
+++ b/src/coreclr/vm/gcinfodecoder.cpp
@@ -111,6 +111,8 @@ GcInfoDecoder::GcInfoDecoder(
GcInfoHeaderFlags headerFlags;
bool slimHeader = (m_Reader.ReadOneFast() == 0);
+ // Use flag mask to bail out early if we already decoded all the pieces that caller requested
+ int remainingFlags = flags == DECODE_EVERYTHING ? ~0 : flags;
if (slimHeader)
{
@@ -142,14 +144,21 @@ GcInfoDecoder::GcInfoDecoder(
m_ReturnKind =
(ReturnKind)((UINT32)m_Reader.Read(returnKindBits));
- if (flags == DECODE_RETURN_KIND) {
+ remainingFlags &= ~(DECODE_RETURN_KIND | DECODE_VARARG);
+#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
+ remainingFlags &= ~DECODE_HAS_TAILCALLS;
+#endif
+ if (remainingFlags == 0)
+ {
// Bail, if we've decoded enough,
return;
}
m_CodeLength = (UINT32) DENORMALIZE_CODE_LENGTH((UINT32) m_Reader.DecodeVarLengthUnsigned(CODE_LENGTH_ENCBASE));
- if (flags == DECODE_CODE_LENGTH) {
+ remainingFlags &= ~DECODE_CODE_LENGTH;
+ if (remainingFlags == 0)
+ {
// Bail, if we've decoded enough,
return;
}
@@ -181,7 +190,9 @@ GcInfoDecoder::GcInfoDecoder(
m_ValidRangeStart = m_ValidRangeEnd = 0;
}
- if (flags == DECODE_PROLOG_LENGTH) {
+ remainingFlags &= ~DECODE_PROLOG_LENGTH;
+ if (remainingFlags == 0)
+ {
// Bail, if we've decoded enough,
return;
}
@@ -196,7 +207,9 @@ GcInfoDecoder::GcInfoDecoder(
m_SecurityObjectStackSlot = NO_SECURITY_OBJECT;
}
- if (flags == DECODE_SECURITY_OBJECT) {
+ remainingFlags &= ~DECODE_SECURITY_OBJECT;
+ if (remainingFlags == 0)
+ {
// Bail, if we've decoded enough,
return;
}
@@ -211,7 +224,9 @@ GcInfoDecoder::GcInfoDecoder(
m_GSCookieStackSlot = NO_GS_COOKIE;
}
- if (flags == DECODE_GS_COOKIE) {
+ remainingFlags &= ~DECODE_GS_COOKIE;
+ if (remainingFlags == 0)
+ {
// Bail, if we've decoded enough,
return;
}
@@ -227,7 +242,9 @@ GcInfoDecoder::GcInfoDecoder(
m_PSPSymStackSlot = NO_PSP_SYM;
}
- if (flags == DECODE_PSP_SYM) {
+ remainingFlags &= ~DECODE_PSP_SYM;
+ if (remainingFlags == 0)
+ {
// Bail, if we've decoded enough,
return;
}
@@ -242,7 +259,9 @@ GcInfoDecoder::GcInfoDecoder(
m_GenericsInstContextStackSlot = NO_GENERICS_INST_CONTEXT;
}
- if (flags == DECODE_GENERICS_INST_CONTEXT) {
+ remainingFlags &= ~DECODE_GENERICS_INST_CONTEXT;
+ if (remainingFlags == 0)
+ {
// Bail, if we've decoded enough,
return;
}
@@ -278,6 +297,13 @@ GcInfoDecoder::GcInfoDecoder(
#endif
}
+ remainingFlags &= ~DECODE_EDIT_AND_CONTINUE;
+ if (remainingFlags == 0)
+ {
+ // Bail, if we've decoded enough,
+ return;
+ }
+
if (hasReversePInvokeFrame)
{
m_ReversePInvokeFrameStackSlot = (INT32)DENORMALIZE_STACK_SLOT(m_Reader.DecodeVarLengthSigned(REVERSE_PINVOKE_FRAME_ENCBASE));
@@ -287,6 +313,12 @@ GcInfoDecoder::GcInfoDecoder(
m_ReversePInvokeFrameStackSlot = NO_REVERSE_PINVOKE_FRAME;
}
+ remainingFlags &= ~DECODE_REVERSE_PINVOKE_VAR;
+ if (remainingFlags == 0)
+ {
+ // Bail, if we've decoded enough,
+ return;
+ }
#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA
if (slimHeader)