Skip to content

MsQuic interop - #1

Closed
ManickaP wants to merge 13 commits into
mainfrom
mapichov/quic_interop
Closed

MsQuic interop#1
ManickaP wants to merge 13 commits into
mainfrom
mapichov/quic_interop

Conversation

@ManickaP

Copy link
Copy Markdown
Owner

No description provided.

@ManickaP
ManickaPforce-pushed the mapichov/quic_interop branch from 0176c8a to b766f73CompareApril 9, 2022 11:47
Comment on lines 71 to 63

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thhous-msft I wonder if we should post-process and remove the type prefix from our interop layer, so this would stay NONE.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'd be fine doing that. It works a lot better from C# that would.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you're just going to manually copy this in every time you sync to the latest MsQuic?

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also have to make all the classes/structs/enums internal, so I cannot just take it as it is.
We could publish the interop lib and consume that, but that would mean setting up infra for it and is not so straightforward.

Do you have any other way to consume this in mind?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, SocketAddress.Buffer does not take into account macOS having the family in a different location then linux. But, QuicAddr is identical to sockaddr, so theoretically if there is an internal SocketAddress to sockaddr helper, that would work fine.

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nibanks Is it possible for us to change the copyright here to:

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

???

This is what the compiler/analyzer wants from me.

Of course, I can figure out where the message comes from and whether we can skip it here in case it's not possible to change due to legal reasons.

Comment on lines 150 to 151

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code does

publicstaticunsafeIntPtrUnsafeAddrOfPinnedArrayElement<T>(T[]arr!!,intindex){void*pRawData=Unsafe.AsPointer(refMemoryMarshal.GetArrayDataReference(arr));return(IntPtr)((byte*)pRawData+(uint)index*(nuint)Unsafe.SizeOf<T>());}

So I suppose it should be pinned because if buffers is not pinned this makes (QUIC_BUFFER*)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0) a pointer to somewhere inside an unpinned array

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I thought, but we had it like this since forever, which confused me.

@ManickaP
ManickaPforce-pushed the mapichov/quic_interop branch from 37c6fa6 to 46a7401CompareApril 20, 2022 18:21
@ManickaP

Copy link
Copy Markdown
OwnerAuthor

Closing in favor of dotnet#68288

ManickaP pushed a commit that referenced this pull request May 26, 2022
This adds support for EnC on arm64. A couple of notes on the
implementation compared to x64:
- On x64 we get the fixed stack size from unwind info. However, for the
frames we set up on arm64 for EnC it is not possible to extract the
frame size from there because their prologs generally look like
stp fp, lr, [sp,#-16]!
mov fp, sp
sub sp, sp, dotnet#144
with unwind codes like the following:
set_fp; mov fp, sp
save_fplr_x #1 (0x01); tp fp, lr, [sp, #-16]!
As can be seen, it is not possible to get the fixed stack size from
unwind info in this case. Instead we pass it through the GC info that
already has a section for EnC data.
- On arm64 the JIT is required to place the PSPSym at the same offset
from caller-SP for both the main function and for funclets. Due to
this we try to allocate the PSPSym as early as possible in the main
function and we must take some care in funclets. However, this
conflicts with the EnC frame header that the JIT uses to place values
that must be preserved on EnC transitions. This is currently
callee-saved registers and the MonitorAcquired boolean.
Before this change we were allocating PSPSym above (before) the
monitor acquired boolean, but we now have to allocate MonitorAcquired
first, particularly because the size of the preserved header cannot
change on EnC transitions, while the PSPSym can disappear or appear.
This changes frame allocation slightly for synchronized functions.
ManickaP pushed a commit that referenced this pull request Jun 8, 2022
These helpers are used to report names of things in warnings. The functional changes are:
* For method parameters, use the parameter name if available (and only if not fallback to the #1 notation)
* For property accessor methods, use the C# naming scheme, so for example Type.Property.get instead of Type.get_Property.
Both of these changes are in preparation to bring NativeAOT closer in behavior to ILLink and the trim analyzers.
For this I moved some of the helpers to the common shared code.
Some unrelated code cleanup as well.
Co-authored-by: Michal Strehovský <MichalStrehovsky@users.noreply.github.com>
ManickaP pushed a commit that referenced this pull request Jun 27, 2022
* Initial implementation for contract customization
fix build errors
Move converter rooting to DefaultJsonTypeInfoResolver so that it can be used standalone
Fix ConfigurationList.IsReadOnly
Minor refactorings (#1)
* Makes the following changes:
* Move singleton initialization for DefaultTypeInfoResolver behind a static property.
* Consolidate JsonSerializerContext & IJsonTypeInfoResolver values to a single field.
* Move reflection fallback logic away from JsonSerializerContext and into JsonSerializerOptions
* Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs
* remove testing of removed field
Simplify the JsonTypeInfo.CreateObject implemenetation (#2)
* Simplify the JsonTypeInfo.CreateObject implemenetation
* Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.cs
* Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.cs
Co-authored-by: Krzysztof Wicher <mordotymoja@gmail.com>
Co-authored-by: Krzysztof Wicher <mordotymoja@gmail.com>
Tests and fixes for JsonTypeInfoKind.None
TypeInfo type mismatch tests
Allow setting NumberHandling on JsonTypeInfoKind.None
test resolver returning wrong type of options
JsonTypeInfo/JsonPropertyInfo mutability tests
rename test file
Move default converter rooting responsibility behind DefaultJsonTypeInfoResolver (#3)
* Move default converter rooting responsibility behind DefaultJsonTypeInfoResolver
* address feedback
Add simple test for using JsonTypeInfo<T> with APIs directly taking it
fix and tests for untyped/typed CreateObject
uncomment test cases, remove todo
More tests and tiny fixes
Add a JsonTypeInfoResolver.Combine test for JsonSerializerContext (#4)
* Fix JsonTypeInfoResolver.Combine for JsonSerializerContext
* Break up failing test
Fix simple scenarios for combining contexts (#6)
* Fix simple scenarios for combining contexts
* feedback
JsonSerializerContext combine test with different camel casing
Remove unneeded virtual calls & branching when accessing Get & Set delegates (#7)
JsonPropertyInfo tests everything minus ShouldSerialize & NumberHandling
Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs
Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs
throw InvalidOperationException rather than ArgumentNullException for source gen when PropertyInfo.Name is assigned through JsonPropertyInfoValues
tests for duplicated property names and JsonPropertyInfo.NumberHandling
Add tests for NumberHandling and failing tests for ShouldSerialize
disable the failing test and add extra checks
disable remainder of the failing ShouldSerialize tests, fix working one
Fix ShouldSerialize and IgnoreCondition interop
Add failing tests for CreateObject + parametrized constructors
Fix CreateObject support for JsonConstructor types (#10)
* Fix CreateObject support for JsonConstructor types
* address feedback
Make contexts more combinator friendly (#9)
* Make contexts more combinator friendly
* remove converter cache
* redesign test to account for JsonConstructorAttribute
* Combine unit tests
* address feedback
* Add acceptance tests for DataContract attributes & Specified pattern (#11)
* Add private field serialization acceptance test (#13)
* tests, PR feedback (#14)
* PR feedback and extra tests
* Shorten class name, remove incorrect check (not true for polimorphic cases)
* Make parameter matching for custom properties map property Name with parameter (dotnet#16)
* Test static initialization with JsonTypeInfo (#17)
* Fix test failures and proper fix this time (dotnet#18)
* Fix test failures and proper fix this time
* reinstate ActiveIssueAttribute
* PR feedback and adjust couple of tests which don't set TypeInfoResolver
* fix IAsyncEnumerable tests
* Lock JsonSerializerOptions in JsonTypeInfo.EnsureConfigured()
Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
ManickaP pushed a commit that referenced this pull request Jul 1, 2022
E.g.,
Update LSRA "Allocating Registers" table description.
Dump nodes added during resolution, e.g.:
```
BB29 bottom (BB08->BB08): move V25 from STK to rdi (Critical)
N001 ( 1, 1) [001174] ----------z t1174 = LCL_VAR int V25 cse4 rdi REG rdi
```
Dump more data in the LSRA block sequence data:
```
-BB03( 16 )
-BB04( 4 )
+BB03 ( 16 ) critical-in critical-out
+BB04 ( 4 ) critical-out
```
When dumping various flow bitvectors, annotate the bitvectors better:
```
-BB25 in gen out
-0000000000000000
-0000000000000003 CSE #1.c
-0000000000000003 CSE #1.c
+BB25
+ in: 0000000000000000
+gen: 0000000000000003 CSE #1.c
+out: 0000000000000003 CSE #1.c
```
Dump hoisting bitvectors using the sorting number:
```
- USEDEF (5)={V04 V00 V01 V02 V03}
+ USEDEF (5)={V00 V01 V02 V03 V04}
```
Also, fix various typos and formatting.
ManickaP pushed a commit that referenced this pull request Aug 29, 2022
* WIP: add gRPC tests
* Fix AOT and trimming
* WIP
* Implement IncludeNetworkSecurityConfig
* Use IncludeNetworkSecurityConfig
* Fix gRPC test
* Avoid git checkout
* Remove unnecessary code
* WIP: start working on CI configuration
* Remove WinHttpHandler
* Fix problem with SSL
* Change server host
* Setup CI (#1)
* Get Docker container building & exported via test build
* Changes
* Add missing pfx certificate
* changes
* cleanup
Co-authored-by: Simon Rozsival <simon@rozsival.com>
* Use tls
* Update yml
* Revert changes to the mono Android sample app
* Bump android image version
* Bump image version
* Enable TLS
* Remove hardcoded package versions
* Update package versions
* Update package versions
* Rename pipeline
* Move interop tests website dependencies versions to Versions.props
* Add cred scan supression for the interop test server private key
* Fix licenses
* Remove dependencies
* Fix path to Versions.props
* Remove unnecessary dependency version
* Fix building docker image
* Change pfx password
Co-authored-by: Jo Shields <directhex@apebox.org>
ManickaP pushed a commit that referenced this pull request Jan 2, 2023
* switch to managed thread ID in Lock
* fattening the lock
* __declspec(selectany)
* few tweaks
* fairness
* more room for thread ids
* remove CurrentNativeThreadId
* couple fixes
* fix win-arm64 build
* win-arm64 build , another try
* Apply suggestions from code review
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
* fix after renaming
* do not report successful spin if thread has waited
* keep extern and undo mangling of tls_CurrentThread in asm
* use SyncTable indexer in less perf-sensitive places.
* GetNewHashCode just delegate to shared random
* Apply suggestions from code review
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
* unchecked const conversion
* some refactoring comments and typos
* min number of spins in the backoff
* moved CurrentManagedThreadIdUnchecked to ManagedThreadId
* Use `-1` to report success and allow using element #1 in the SyncTable
* use threadstatic for managed thread ID
* check before calling RhGetProcessCpuCount
* use 0 as default thread ID
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
ManickaP pushed a commit that referenced this pull request Jan 18, 2023
* Fix the MacOS remote unwinder for VS4Mac
The wrong module was being passed to the remote unwinder because the load bias for shared modules
was being calculated incorrectly.
Issue: dotnet#63309
* Fix native frame unwind in syscall on arm64 for VS4Mac crash report
From PR in main: dotnet#63598
Add arm64 version of StepWithCompactNoEncoding for syscall leaf node wrappers that have compact encoding of 0.
Fix ReadCompactEncodingRegister so it actually decrements the addr.
Change StepWithCompactEncodingArm64 to match what MacOS libunwind does for framed and frameless stepping.
arm64 can have frames with the same SP (but different IPs). Increment SP for this condition so createdump's unwind
loop doesn't break out on the "SP not increasing" check and the frames are added to the thread frame list in the
correct order.
Add getting the unwind info for tail called functions like this:
__ZL14PROCEndProcessPvji:
36630: f6 57 bd a9 stp x22, x21, [sp, #-48]!
36634: f4 4f 01 a9 stp x20, x19, [sp, dotnet#16]
36638: fd 7b 02 a9 stp x29, x30, [sp, dotnet#32]
3663c: fd 83 00 91 add x29, sp, dotnet#32
...
367ac: e9 01 80 52 mov w9, #15
367b0: 7f 3e 02 71 cmp w19, dotnet#143
367b4: 20 01 88 1a csel w0, w9, w8, eq
367b8: 2e 00 00 94 bl _PROCAbort
_TerminateProcess:
-> 367bc: 22 00 80 52 mov w2, #1
367c0: 9c ff ff 17 b __ZL14PROCEndProcessPvji
The IP (367bc) returns the (incorrect) frameless encoding with nothing on the stack (uses an incorrect LR to unwind). To fix this
get the unwind info for PC -1 which points to PROCEndProcess with the correct unwind info. This matches how lldb unwinds this frame.
Always address module segment to IP lookup list instead of checking the module regions.
Strip pointer authentication bits on PC/LR.
ManickaP pushed a commit that referenced this pull request Jun 9, 2023
…tnet#87189)
This fixes a startup crash on Big Sur:
> error: * Assertion at /Users/runner/work/1/s/src/mono/mono/utils/mono-hwcap-arm64.c:35, condition `res == 0' not met
Because sysctl can't find some of these options:
$ sysctl hw.optional.armv8_crc32
hw.optional.armv8_crc32: 1
$ sysctl hw.optional.arm.FEAT_RDM
sysctl: unknown oid 'hw.optional.arm.FEAT_RDM'
$ sysctl hw.optional.arm.FEAT_DotProd
sysctl: unknown oid 'hw.optional.arm.FEAT_DotProd'
$ sysctl hw.optional.arm.FEAT_SHA1
sysctl: unknown oid 'hw.optional.arm.FEAT_SHA1'
$ sysctl hw.optional.arm.FEAT_SHA256
sysctl: unknown oid 'hw.optional.arm.FEAT_SHA256'
$ sysctl hw.optional.arm.FEAT_AES
sysctl: unknown oid 'hw.optional.arm.FEAT_AES'
Full stack trace:
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
* frame #0: 0x0000010ef37560 libmonosgen-2.0.dylib`monoeg_assertion_message
frame #1: 0x0000010ef375cc libmonosgen-2.0.dylib`mono_assertion_message + 32
frame #2: 0x0000010ef40d6c libmonosgen-2.0.dylib`mono_hwcap_arch_init + 544
frame #3: 0x0000010ef54bd8 libmonosgen-2.0.dylib`mono_hwcap_init + 72
frame #4: 0x0000010ee14dc0 libmonosgen-2.0.dylib`parse_optimizations + 52
frame #5: 0x0000010edbed48 libmonosgen-2.0.dylib`mono_init
frame #6: 0x0000010ee18968 libmonosgen-2.0.dylib`mono_jit_init_version
frame #7: 0x0000010f48a300 libxamarin-dotnet-debug.dylib`xamarin_bridge_initialize + 216
frame #8: 0x0000010f4900a4 libxamarin-dotnet-debug.dylib`xamarin_main + 376
ManickaP pushed a commit that referenced this pull request Nov 30, 2023
Fixesdotnet#95367.
Relevant part of the JitDump:
```
Using `if true` assertions from pred BB02
Assertions in: #1
fgMorphTree BB04, STMT00021 (before)
[000070] DA--------- * STORE_LCL_VAR ubyte V10 tmp9
[000057] ----------- \--* CAST int <- ubyte <- int
[000006] ----------- \--* EQ int
[000004] ----------- +--* LCL_VAR ref V02 tmp1 (last use)
[000055] H---------- \--* CNS_INT(h) ref 'Frozen EmptyPartition`1<Int32> object'
Assertion prop for index #1 in BB04:
[000006] ----------- * EQ int
GenTreeNode creates assertion:
[000070] DA---+----- * STORE_LCL_VAR ubyte V10 tmp9
In BB04 New Local Constant Assertion: V10 == [0000000000000001], index = #2
fgMorphTree BB04, STMT00021 (after)
[000070] DA---+----- * STORE_LCL_VAR ubyte V10 tmp9
[000055] H----+----- \--* CNS_INT(h) int
```
The JitDump is unfinished because the compiler crashes when trying to dump the last line. Clearly, the `CNS_INT` is no longer a handle at that point because we just bashed it to a constant 1.
ManickaP pushed a commit that referenced this pull request Mar 15, 2024
CodeQL flagged various places where we're dereferencing pointers that could be NULL, this PR systematically cleans some of them up via g_assert.
* g_assert result of g_build_path calls
* Allocation failure handling
* mono_class_inflate_generic_class_checked can return NULL
ManickaP pushed a commit that referenced this pull request May 21, 2024
…#102133)
This generalizes the indir reordering optimization (that currently only
triggers for loads) to kick in for GT_STOREIND nodes.
The main complication with doing this is the fact that the data node of
the second indirection needs its own reordering with the previous
indirection. The existing logic works by reordering all nodes between
the first and second indirection that are unrelated to the second
indirection's computation to happen after it. Once that is done we know
that there are no uses of the first indirection's result between it and
the second indirection, so after doing the necessary interference checks
we can safely move the previous indirection to happen after the data
node of the second indirection.
Example:
```csharp
class Body { public double x, y, z, vx, vy, vz, mass; }
static void Advance(double dt, Body[] bodies)
{
foreach (Body b in bodies)
{
b.x += dt * b.vx;
b.y += dt * b.vy;
b.z += dt * b.vz;
}
}
```
Diff:
```diff
@@ -1,18 +1,17 @@
-G_M55007_IG04: ;; offset=0x001C
+G_M55007_IG04: ;; offset=0x0020
ldr x3, [x0, w1, UXTW #3]
ldp d16, d17, [x3, #0x08]
ldp d18, d19, [x3, #0x20]
fmul d18, d0, d18
fadd d16, d16, d18
- str d16, [x3, #0x08]
- fmul d16, d0, d19
- fadd d16, d17, d16
- str d16, [x3, #0x10]
+ fmul d18, d0, d19
+ fadd d17, d17, d18
+ stp d16, d17, [x3, #0x08]
ldr d16, [x3, #0x18]
ldr d17, [x3, #0x30]
fmul d17, d0, d17
fadd d16, d16, d17
str d16, [x3, #0x18]
add w1, w1, #1
cmp w2, w1
bgt G_M55007_IG04
```
ManickaP pushed a commit that referenced this pull request Sep 13, 2024
* bug #1: don't allow for values out of the SerializationRecordType enum range
* bug #2: throw SerializationException rather than KeyNotFoundException when the referenced record is missing or it points to a record of different type
* bug #3: throw SerializationException rather than FormatException when it's being thrown by BinaryReader (or sth else that we use)
* bug #4: document the fact that IOException can be thrown
* bug #5: throw SerializationException rather than OverflowException when parsing the decimal fails
* bug #6: 0 and 17 are illegal values for PrimitiveType enum
* bug #7: throw SerializationException when a surrogate character is read (so far an ArgumentException was thrown)
ManickaP pushed a commit that referenced this pull request Mar 14, 2025
* JIT: Introduce `LclVarDsc::lvIsMultiRegDest`
With recent work to expand returned promoted locals into `FIELD_LIST`
the only "whole references" of promoted locals we should see is when
stored from a multi-reg node. This is the only knowledge the backend
should need for correctness purposes, so introduce a bit to track this
property, and switch the backend to check this instead.
The existing `lvIsMultiRegRet` is essentially this + whether the local
is returned. We should be able to remove this, but it is currently used
for some heuristics in old promotion, so keep it around for now.
* JIT: Add some more constant folding in lowering
Add folding for shifts and certain binops that are now getting produced
late due to returned `FIELD_LIST` nodes.
win-arm64 example:
```csharp
[MethodImpl(MethodImplOptions.NoInlining)]
static ValueTask<byte> Foo()
{
return new ValueTask<byte>(123);
}
```
```diff
G_M17084_IG02: ;; offset=0x0008
mov x0, xzr
- mov w1, #1
- mov w2, wzr
- mov w3, dotnet#123
- orr w2, w2, w3, LSL dotnet#16
- orr w1, w2, w1, LSL dotnet#24
- ;; size=24 bbWeight=1 PerfScore 4.00
+ mov w1, #0x17B0000
+ ;; size=8 bbWeight=1 PerfScore 1.00
```
* Feedback
ManickaP pushed a commit that referenced this pull request Apr 7, 2025
…otnet#114227)
Presence of `.cctor` in `Thread` can cause circular dependency if Lock needs to block while Thread .cctor has not run yet.
1. Lock needs to wait on a WaitHandle
2. WaitHandle needs Thread.CurrentThread
3. if Thread's .cctor has not run yet, it needs to run. (it is unusual for this to be the first use of Thread, but the activation pattern in dotnet#113949 made it possible)
4. .cctor needs to take a Lock, so we go to `#1`
Fixes: dotnet#113949
ManickaP pushed a commit that referenced this pull request Sep 30, 2025
ManickaP pushed a commit that referenced this pull request Sep 30, 2025
…ds from dotnet#27912 (Flow System.Text.Rune through more APIs)) (dotnet#120145)
* Fix tests from dotnet#117168
* Add `SyncTextWriter` overloads as well
* Add missing overloads to BroadcastingTextWriter
* Reapply "Add methods from dotnet#27912 (Flow System.Text.Rune through more APIs) (#1…" (dotnet#120138)
This reverts commit be80737.
* Override the TextWrite Rune overloads in IndentedTextWriter
---------
Co-authored-by: Tarek Mahmoud Sayed <tarekms@microsoft.com>
ManickaP pushed a commit that referenced this pull request Feb 16, 2026
…er (dotnet#123735)
From discussion, opting into enabling the crash chaining is more
correct.
<s>The previously registered signal action/handler aren't guaranteed to
return, so we lose out on notifying shutdown and creating a dump in
those cases. Specifically, PROCCreateCrashDumpIfEnabled would be the
last chance to provide the managed context for the thread that crashed.
e.g. On Android CoreCLR, it seems that, by default, signal handlers are
already registered by Android's runtime
(/apex/com.android.runtime/bin/linker64 +
/system/lib64/libandroid_runtime.so). Whenever an unhandled synchronous
fault occurs, the previously registered handler will not return back to
invoke_previous_action and aborts the thread itself, so
PROCCreateCrashDumpIfEnabled will not be hit.</s>
## Sigsegv behavior Android CoreCLR vs other platforms
### Android CoreCLR
When intentionally writing to NULL (sigsegv) on Android CoreCLR, the
previously registered signal handler goes down this path
https://github.com/dotnet/runtime/blob/40e8c73b8f3b5f478a9bf03cf55c71d0608a8855/src/coreclr/pal/src/exception/signal.cpp#L454,
and the thread aborts before hitting PROCNotifyProcessShutdown and
PROCCreateCrashDumpIfEnabled.
### MacOS/Linux/NativeAOT(linux)
On MacOS, Linux, NativeAOT (Only checked linux at time of writing), the
same intentional SIGSEGV will hit
https://github.com/dotnet/runtime/blob/40e8c73b8f3b5f478a9bf03cf55c71d0608a8855/src/coreclr/pal/src/exception/signal.cpp#L431-L448
instead because there is no previously registered signal handler. In
those cases, PROCCreateCrashDumpIfEnabled is hit and managed callstacks
are captured in the dump.
## History investigation
From a github history dive, I didn't spot anything in particular
requiring the previous signal handler to be invoked before
PROCNotifyProcessShutdown + PROCCreateCrashDumpIfEnabled.
PROCNotifyProcessShutdown was first introduced in
dotnet@1433c3f.
It doesn't seem to state a particular reason for invoking it after the
previous signal handler.
PROCCreateCrashDumpIfEnabled was added to signal.cpp in
dotnet@7f9bd2c
because the PROCNotifyProcessShutdown didn't create a crash dump. It
doesn't state any particular reason for being invoked after the
previously registered signal handler, and was probably just placed next
to PROCNotifyProcessShutdown.
`invoke_previous_action` was introduced in
dotnet@a740f65
and was refactoring while maintaining the order.
## Android CoreCLR behavior after swapping order
Locally, I have POC changes to emit managed callstacks in Android's
PROCCreateCrashDumpIfEnabled.
```
01-28 17:26:40.951 2416 2440 F DOTNET : Native crash detected; attempting managed stack trace.
01-28 17:26:40.951 2416 2440 F DOTNET : {"stack":[
01-28 17:26:40.951 2416 2440 F DOTNET : {"ip":"0x0","module":"0x0","offset":"0x0","name":"Program.MemSet(Void*, Int32, UIntPtr)"},
01-28 17:26:40.951 2416 2440 F DOTNET : {"ip":"0x78d981145973","module":"0x0","offset":"0x0","name":"Program.MemSet(Void*, Int32, UIntPtr)"},
01-28 17:26:40.951 2416 2440 F DOTNET : {"ip":"0x78d981145973","module":"0x0","offset":"0x73","name":"Program.ForceNativeSegv()"},
01-28 17:26:40.951 2416 2440 F DOTNET : {"ip":"0x78d981141b60","module":"0x0","offset":"0x70","name":"Program.Main(System.String[])"}
01-28 17:26:40.951 2416 2440 F DOTNET : ]}
01-28 17:26:40.952 2416 2440 F DOTNET : Crash dump hook completed.
--------- beginning of crash
01-28 17:26:40.952 2416 2440 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 2440 (.dot.MonoRunner), pid 2416 (ulator.JIT.Test)
.....
01-28 17:26:46.882 2921 2921 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-28 17:26:46.882 2921 2921 F DEBUG : Build fingerprint: 'google/sdk_gphone64_x86_64/emu64xa:16/BE2A.250530.026.D1/13818094:user/release-keys'
01-28 17:26:46.882 2921 2921 F DEBUG : Revision: '0'
01-28 17:26:46.882 2921 2921 F DEBUG : ABI: 'x86_64'
01-28 17:26:46.882 2921 2921 F DEBUG : Timestamp: 2026-01-28 17:26:41.492831700-0500
01-28 17:26:46.882 2921 2921 F DEBUG : Process uptime: 20s
01-28 17:26:46.883 2921 2921 F DEBUG : Cmdline: net.dot.Android.Device_Emulator.JIT.Test
01-28 17:26:46.883 2921 2921 F DEBUG : pid: 2416, tid: 2440, name: .dot.MonoRunner >>> net.dot.Android.Device_Emulator.JIT.Test <<<
01-28 17:26:46.883 2921 2921 F DEBUG : uid: 10219
01-28 17:26:46.883 2921 2921 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000
01-28 17:26:46.883 2921 2921 F DEBUG : Cause: null pointer dereference
01-28 17:26:46.883 2921 2921 F DEBUG : Abort message: 'CoreCLR: previous handler for '
01-28 17:26:46.883 2921 2921 F DEBUG : rax 0000000000000000 rbx 000078da87ffade0 rcx 0000000000000000 rdx 0000000000000001
01-28 17:26:46.884 1237 1297 I s.nexuslauncher: AssetManager2(0x78dd08cd9178) locale list changing from [] to [en-US]
01-28 17:26:46.903 2447 2594 I BugleNotifications: Creating notification input ids [CONTEXT im_entry_input="" im_notification_input="" im_settings_store_input="" im_final_input="" ]
01-28 17:26:46.905 2921 2921 F DEBUG : r8 00007ffcde5a8080 r9 34d9bb0e67871eb0 r10 000078ddb4111870 r11 0000000000000293
01-28 17:26:46.906 2921 2921 F DEBUG : r12 0000000000000001 r13 000078da87ffafa0 r14 0000000000000000 r15 000078da87ffaf18
01-28 17:26:46.906 2921 2921 F DEBUG : rdi 0000000000000000 rsi 0000000000000000
01-28 17:26:46.906 2921 2921 F DEBUG : rbp 000078da87ffac40 rsp 000078da87ffabc8 rip 000078ddb41118a2
01-28 17:26:46.906 2921 2921 F DEBUG : 2 total frames
01-28 17:26:46.906 2921 2921 F DEBUG : backtrace:
01-28 17:26:46.906 2921 2921 F DEBUG : #00 pc 000000000008f8a2 /apex/com.android.runtime/lib64/bionic/libc.so (memset_avx2+50) (BuildId: fcb82240218d1473de1e3d2137c0be35)
01-28 17:26:46.906 2921 2921 F DEBUG : #1 pc 0000000000049972 /memfd:doublemapper (deleted) (offset 0x111000)
```
Now theres a window to log managed callstacks before the original signal
handler aborts and triggers a tombstone.
## Android Mono behavior
Mono provides two embeddings APIs to configure signal and crash chaining
https://github.com/dotnet/runtime/blob/61d3943de41e948bb0ecf871b92eb456d2dd74d8/src/mono/mono/mini/driver.c#L2864-L2894
that determine whether synchronous faults would chain
https://github.com/dotnet/runtime/blob/61d3943de41e948bb0ecf871b92eb456d2dd74d8/src/mono/mono/mini/mini-runtime.c#L3892-L3903
They would only chain to the previous signal handler
https://github.com/dotnet/runtime/blob/61d3943de41e948bb0ecf871b92eb456d2dd74d8/src/mono/mono/mini/mini-posix.c#L193-L210
only after attempting to walk native and managed stacks
https://github.com/dotnet/runtime/blob/61d3943de41e948bb0ecf871b92eb456d2dd74d8/src/mono/mono/mini/mini-exceptions.c#L2992-L3012
## Alternatives
If there is any particular reason to preserve the order of
sa_sigaction/sa_handler with respect to PROCNotifyProcessShutdown and
PROCCreateCrashDumpIfEnabled for CoreCLR, a config knob can be added to
allow Android CoreCLR to opt into the swapped ordering behavior. This
may be in the form of config property key/values
https://github.com/dotnet/runtime/blob/54ca569eb62800cdb725d776e3dd2e564028594d/src/coreclr/dlls/mscoree/exports.cpp#L237-L238
or `clrconfigvalues`. That way AndroidSDK/AndroidAppBuilder may opt-in
at build-time.
Given that the history of the ordering didn't reveal any problems with
swapping the order, we can fallback to this behavior if the order swap
causes problems down the line.
The other way around is more restrictive. Should we first introduce all
the overhead to enable an opt-in/opt-out config knob, and later discover
that no platforms need to invoke their previous handlers before
PROCNotifyProcessShutdown/PROCCreateCrashDumpIfEnabled, it seems harder
to justify removing the knob.
ManickaP added a commit that referenced this pull request Mar 3, 2026
ManickaP added a commit that referenced this pull request Mar 11, 2026
ManickaP pushed a commit that referenced this pull request Mar 23, 2026
…otnet#124642)
## Summary
Fixesdotnet#123621
When a constant-folded operand appears **after** a non-constant operand
in a short-circuit `&&` expression (e.g., `v == 2 && Environment.NewLine
!= "\r\n"`), callee inlining can leave dead local stores in the return
block. The `isReturnBool` lambda in `fgFoldCondToReturnBlock` required
`hasSingleStmt()`, which caused the optimization to bail out when these
dead stores were present, resulting in suboptimal branching codegen.
### Changes
- **`src/coreclr/jit/optimizebools.cpp`**: Relax the `hasSingleStmt()`
constraint in `isReturnBool` to allow preceding statements as long as
they have no globally visible side effects
(`GTF_GLOBALLY_VISIBLE_SIDE_EFFECTS`). This enables
`fgFoldCondToReturnBlock` to fold the conditional into a branchless
return even when dead local stores from inlining remain in the block.
### Before (ARM64, `Inline_After`)
```asm
cmp w0, #2
bne G_M4495_IG04
mov w0, #1
ret
G_M4495_IG04:
mov w0, #0
ret
```
### After (ARM64, `Inline_After`)
```asm
cmp w0, #2
cset x0, eq
ret
```
## Test plan
- [x] Added regression test `Runtime_123621` covering the original issue
pattern
- [x] Verified `Hoisted`, `Inline_Before`, and `Inline_After` all
produce identical branchless codegen (`cset` on ARM64)
- [x] Verified existing `DevDiv_168744` regression test still passes
- [x] Verified side-effect-ful blocks are correctly excluded from the
optimization
ManickaP pushed a commit that referenced this pull request Mar 25, 2026
i.e. Fold: (-(x)) == 0 -> x == 0
arm64 asmdiffs
Diffs are based on <span style="color:#1460aa">436,095</span> contexts
(<span style="color:#1460aa">26,618</span> MinOpts, <span
style="color:#1460aa">409,477</span> FullOpts).
<details>
<summary>Overall (<span style="color:green">-40</span> bytes)</summary>
<div style="margin-left:1em">
|Collection|Base size (bytes)|Diff size (bytes)|PerfScore in Diffs
|---|--:|--:|--:|
|libraries_tests_no_tiered_compilation.run.linux.arm64.Release.mch|183,146,276|<span
style="color:green">-40</span>|<span style="color:green">-0.09%</span>|
|benchmarks.run.linux.arm64.checked.mch|21,285,888|+0|0.00%|
|smoke_tests.nativeaot.linux.arm64.checked.mch|3,003,400|+0|0.00%|
</div></details>
<details>
<summary>FullOpts (<span style="color:green">-40</span> bytes)</summary>
<div style="margin-left:1em">
|Collection|Base size (bytes)|Diff size (bytes)|PerfScore in Diffs
|---|--:|--:|--:|
|libraries_tests_no_tiered_compilation.run.linux.arm64.Release.mch|168,630,412|<span
style="color:green">-40</span>|<span style="color:green">-0.09%</span>|
|benchmarks.run.linux.arm64.checked.mch|20,953,436|+0|0.00%|
|smoke_tests.nativeaot.linux.arm64.checked.mch|3,001,776|+0|0.00%|
</div></details>
<details>
<summary>Example diffs</summary>
<div style="margin-left:1em">
<details>
<summary>libraries_tests_no_tiered_compilation.run.linux.arm64.Release.mch</summary>
<div style="margin-left:1em">
<details>
<summary><span style="color:green">-4</span> (<span
style="color:green">-1.27%</span>) : 142473.dasm -
System.IO.Pipelines.Tests.BufferSegmentPoolTest:GetSegments(System.IO.Pipelines.ReadResult):System.Collections.Generic.List`1[System.Buffers.ReadOnlySequenceSegment`1[byte]]
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -53,8 +53,7 @@ G_M13215_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0001 {x0}, byre
G_M13215_IG03: ; bbWeight=0.50, gcrefRegs=80002 {x1 x19}, byrefRegs=0000 {}, byref, isz
asr w2, w2, dotnet#31
lsl w2, w2, #1
- add w0, w2, w0, ASR dotnet#31
- negs w0, w0
+ adds w0, w2, w0, ASR dotnet#31
bne G_M13215_IG04
movz x0, #0xD1FFAB1E
movk x0, #0xD1FFAB1E LSL dotnet#16
@@ -76,7 +75,7 @@ G_M13215_IG03: ; bbWeight=0.50, gcrefRegs=80002 {x1 x19}, byrefRegs=0000
mov x19, x0
; gcrRegs +[x19]
b G_M13215_IG05
- ;; size=68 bbWeight=0.50 PerfScore 6.00
+ ;; size=64 bbWeight=0.50 PerfScore 5.75
G_M13215_IG04: ; bbWeight=0.50, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
; gcrRegs -[x0 x19-x20]
mov x20, xzr
@@ -179,7 +178,7 @@ G_M13215_IG13: ; bbWeight=0, gcrefRegs=580000 {x19 x20 x22}, byrefRegs=00
b G_M13215_IG06
;; size=12 bbWeight=0 PerfScore 0.00
-; Total bytes of code 316, prolog size 16, PerfScore 140.93, instruction count 79, allocated bytes for code 316 (MethodHash=c6bccc60) for method System.IO.Pipelines.Tests.BufferSegmentPoolTest:GetSegments(System.IO.Pipelines.ReadResult):System.Collections.Generic.List`1[System.Buffers.ReadOnlySequenceSegment`1[byte]] (FullOpts)
+; Total bytes of code 312, prolog size 16, PerfScore 140.68, instruction count 78, allocated bytes for code 312 (MethodHash=c6bccc60) for method System.IO.Pipelines.Tests.BufferSegmentPoolTest:GetSegments(System.IO.Pipelines.ReadResult):System.Collections.Generic.List`1[System.Buffers.ReadOnlySequenceSegment`1[byte]] (FullOpts)
; ============================================================
Unwind Info:
@@ -190,7 +189,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 79 (0x0004f) Actual length = 316 (0x00013c)
+ Function Length : 78 (0x0004e) Actual length = 312 (0x000138)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
<details>
<summary><span style="color:green">-4</span> (<span
style="color:green">-0.27%</span>) : 162917.dasm -
System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory():this
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -531,10 +531,9 @@ G_M17523_IG25: ; bbWeight=1, gcrefRegs=400002 {x1 x22}, byrefRegs=0000 {}
G_M17523_IG26: ; bbWeight=0.50, gcrefRegs=80002 {x1 x19}, byrefRegs=0000 {}, byref, isz
asr w0, w0, dotnet#31
lsl w0, w0, #1
- add w0, w0, w2, ASR dotnet#31
- negs w0, w0
+ adds w0, w0, w2, ASR dotnet#31
beq G_M17523_IG29
- ;; size=20 bbWeight=0.50 PerfScore 2.25
+ ;; size=16 bbWeight=0.50 PerfScore 2.00
G_M17523_IG27: ; bbWeight=0.50, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
; gcrRegs -[x1 x19]
mov w19, wzr
@@ -733,7 +732,7 @@ G_M17523_IG43: ; bbWeight=0.00, gcrefRegs=0001 {x0}, byrefRegs=0000 {}, b
brk #0
;; size=32 bbWeight=0.00 PerfScore 0.00
-; Total bytes of code 1488, prolog size 36, PerfScore 200.96, instruction count 372, allocated bytes for code 1488 (MethodHash=abb9bb8c) for method System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory():this (FullOpts)
+; Total bytes of code 1484, prolog size 36, PerfScore 200.71, instruction count 371, allocated bytes for code 1484 (MethodHash=abb9bb8c) for method System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory():this (FullOpts)
; ============================================================
Unwind Info:
@@ -744,7 +743,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 372 (0x00174) Actual length = 1488 (0x0005d0)
+ Function Length : 371 (0x00173) Actual length = 1484 (0x0005cc)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
<details>
<summary><span style="color:green">-4</span> (<span
style="color:green">-0.26%</span>) : 162915.dasm -
System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory_String():this
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -208,7 +208,7 @@
; V197 cse1 [V197,T40] ( 2, 1 ) ref -> x0 "CSE #7: moderate"
; V198 cse2 [V198,T44] ( 2, 1 ) int -> x23 "CSE #4: moderate"
; V199 cse3 [V199,T45] ( 2, 1 ) long -> x1 "CSE #5: moderate"
-; V200 cse4 [V200,T33] ( 3, 1.50) int -> x1 "CSE #17: moderate"
+; V200 cse4 [V200,T33] ( 3, 1.50) int -> x1 "CSE dotnet#16: moderate"
; V201 rat0 [V201,T01] ( 3, 5.62) byref -> x1 "fgMakeTemp is creating a new local variable"
; V202 rat1 [V202,T07] ( 5, 3.75) ref -> x0 "replacement local"
; V203 rat2 [V203,T37] ( 3, 1.25) long -> x2 "CSE for expectedClsNode"
@@ -623,8 +623,7 @@ G_M55449_IG30: ; bbWeight=1, gcrefRegs=4180002 {x1 x19 x20 x26}, byrefReg
G_M55449_IG31: ; bbWeight=0.50, gcrefRegs=180000 {x19 x20}, byrefRegs=0000 {}, byref, isz
asr w1, w21, dotnet#31
lsl w1, w1, #1
- add w1, w1, w22, ASR dotnet#31
- negs w1, w1
+ adds w1, w1, w22, ASR dotnet#31
bne G_M55449_IG32
mov x1, x19
; gcrRegs +[x1]
@@ -642,7 +641,7 @@ G_M55449_IG31: ; bbWeight=0.50, gcrefRegs=180000 {x19 x20}, byrefRegs=000
; gcrRegs -[x1 x20]
mov w20, #1
b G_M55449_IG33
- ;; size=68 bbWeight=0.50 PerfScore 6.00
+ ;; size=64 bbWeight=0.50 PerfScore 5.75
G_M55449_IG32: ; bbWeight=0.50, gcrefRegs=80000 {x19}, byrefRegs=0000 {}, byref
mov w20, wzr
;; size=4 bbWeight=0.50 PerfScore 0.25
@@ -776,7 +775,7 @@ G_M55449_IG46: ; bbWeight=0, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
brk #0
;; size=40 bbWeight=0 PerfScore 0.00
-; Total bytes of code 1516, prolog size 48, PerfScore 174.78, instruction count 379, allocated bytes for code 1516 (MethodHash=a4562766) for method System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory_String():this (FullOpts)
+; Total bytes of code 1512, prolog size 48, PerfScore 174.53, instruction count 378, allocated bytes for code 1512 (MethodHash=a4562766) for method System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory_String():this (FullOpts)
; ============================================================
Unwind Info:
@@ -787,7 +786,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 379 (0x0017b) Actual length = 1516 (0x0005ec)
+ Function Length : 378 (0x0017a) Actual length = 1512 (0x0005e8)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
<details>
<summary>+0 (0.00%) : 223365.dasm -
System.Resources.Extensions.DeserializingResourceReader:CompareStringEqualsName(System.String):bool:this
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -106,7 +106,7 @@ G_M52056_IG05: ; bbWeight=0.50, gcrefRegs=500000 {x20 x22}, byrefRegs=000
ldr x3, [x3]
blr x3
; gcrRegs -[x0-x1 x20 x22]
- negs w0, w0
+ cmp w0, #0
cset x0, eq
;; size=40 bbWeight=0.50 PerfScore 4.25
G_M52056_IG06: ; bbWeight=0.50, epilog, nogc, extend
```
</div></details>
<details>
<summary><span style="color:green">-4</span> (<span
style="color:green">-0.02%</span>) : 106573.dasm -
System.Data.Tests.DataTableTest2:Select_ByFilter():this
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -3678,8 +3678,7 @@ G_M43941_IG97: ; bbWeight=1, gcVars=0000000000000000000000000000000000000
G_M43941_IG98: ; bbWeight=4, gcrefRegs=4780004 {x2 x19 x20 x21 x22 x26}, byrefRegs=0000 {}, byref, isz
ldr w1, [x2, #0x08]
ldr w0, [fp, #0xD1FFAB1E]	// [V74 tmp49]
- sub w1, w0, w1
- negs w1, w1
+ subs w1, w0, w1
beq G_M43941_IG90
ldp w0, w1, [x22, #0x10]
add w1, w1, #1
@@ -3688,7 +3687,7 @@ G_M43941_IG98: ; bbWeight=4, gcrefRegs=4780004 {x2 x19 x20 x21 x22 x26},
ldr w1, [x2, #0x08]
cmp w1, w0
bls G_M43941_IG100
- ;; size=48 bbWeight=4 PerfScore 76.00
+ ;; size=44 bbWeight=4 PerfScore 74.00
G_M43941_IG99: ; bbWeight=3.03, gcVars=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 {V06}, gcrefRegs=4780004 {x2 x19 x20 x21 x22 x26}, byrefRegs=0000 {}, gcvars, byref
; GC ptr vars -{V75}
add w1, w0, #1
@@ -7803,7 +7802,7 @@ RWD00 dq	00740053002D0031h, 0067006E00690072h
RWD16 dq	007200740053002Dh, 00310067006E0069h
-; Total bytes of code 18184, prolog size 44, PerfScore 10435.99, instruction count 4546, allocated bytes for code 18184 (MethodHash=c958545a) for method System.Data.Tests.DataTableTest2:Select_ByFilter():this (FullOpts)
+; Total bytes of code 18180, prolog size 44, PerfScore 10433.99, instruction count 4545, allocated bytes for code 18180 (MethodHash=c958545a) for method System.Data.Tests.DataTableTest2:Select_ByFilter():this (FullOpts)
; ============================================================
Unwind Info:
@@ -7814,7 +7813,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 4130 (0x01022) Actual length = 16520 (0x004088)
+ Function Length : 4129 (0x01021) Actual length = 16516 (0x004084)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
<details>
<summary><span style="color:green">-4</span> (<span
style="color:green">-0.16%</span>) : 141855.dasm -
System.IO.Pipelines.Tests.PipePoolTests:GetMemoryOverMaxPoolSizeAllocatesArray():this
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -595,8 +595,7 @@ G_M36412_IG24: ; bbWeight=1, gcrefRegs=B80000 {x19 x20 x21 x23}, byrefReg
G_M36412_IG25: ; bbWeight=0.50, gcrefRegs=B80000 {x19 x20 x21 x23}, byrefRegs=0000 {}, byref, isz
asr w1, w24, dotnet#31
lsl w1, w1, #1
- add w1, w1, w25, ASR dotnet#31
- negs w1, w1
+ adds w1, w1, w25, ASR dotnet#31
bne G_M36412_IG26
mov x1, x20
; gcrRegs +[x1]
@@ -618,7 +617,7 @@ G_M36412_IG25: ; bbWeight=0.50, gcrefRegs=B80000 {x19 x20 x21 x23}, byref
; gcrRegs -[x1] +[x0]
; gcr arg pop 0
b G_M36412_IG27
- ;; size=68 bbWeight=0.50 PerfScore 6.00
+ ;; size=64 bbWeight=0.50 PerfScore 5.75
G_M36412_IG26: ; bbWeight=0.50, gcrefRegs=A80000 {x19 x21 x23}, byrefRegs=0000 {}, byref
; gcrRegs -[x0 x20]
mov x20, xzr
@@ -1232,7 +1231,7 @@ RWD16 dq	<unknown method>
dq	G_M36412_IG51
-; Total bytes of code 2528, prolog size 48, PerfScore 347.37, instruction count 632, allocated bytes for code 2528 (MethodHash=f7d471c3) for method System.IO.Pipelines.Tests.PipePoolTests:GetMemoryOverMaxPoolSizeAllocatesArray():this (FullOpts)
+; Total bytes of code 2524, prolog size 48, PerfScore 347.12, instruction count 631, allocated bytes for code 2524 (MethodHash=f7d471c3) for method System.IO.Pipelines.Tests.PipePoolTests:GetMemoryOverMaxPoolSizeAllocatesArray():this (FullOpts)
; ============================================================
Unwind Info:
@@ -1243,7 +1242,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 591 (0x0024f) Actual length = 2364 (0x00093c)
+ Function Length : 590 (0x0024e) Actual length = 2360 (0x000938)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
</div></details>
<details>
<summary>benchmarks.run.linux.arm64.checked.mch</summary>
<div style="margin-left:1em">
<details>
<summary>+0 (0.00%) : 3177.dasm -
System.Resources.ResourceReader:CompareStringEqualsName(System.String):bool:this
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -106,7 +106,7 @@ G_M1070_IG05: ; bbWeight=0.50, gcrefRegs=500000 {x20 x22}, byrefRegs=0000
ldr x3, [x3]
blr x3
; gcrRegs -[x0-x1 x20 x22]
- negs w0, w0
+ cmp w0, #0
cset x0, eq
;; size=40 bbWeight=0.50 PerfScore 4.25
G_M1070_IG06: ; bbWeight=0.50, epilog, nogc, extend
```
</div></details>
</div></details>
<details>
<summary>smoke_tests.nativeaot.linux.arm64.checked.mch</summary>
<div style="margin-left:1em">
<details>
<summary>+0 (0.00%) : 18583.dasm -
Generics+TestAsyncGVMScenarios:RunAsync() (FullOpts)</summary>
<div style="margin-left:1em">
No diffs found?
</div></details>
<details>
<summary>+0 (0.00%) : 18730.dasm -
Generics+TestAsyncGVMScenarios:AsyncGvm1[System.__Canon]():this
(FullOpts)</summary>
<div style="margin-left:1em">
No diffs found?
</div></details>
<details>
<summary>+0 (0.00%) : 18865.dasm -
Generics+TestAsyncGVMScenarios:AsyncGvm2[System.__Canon]():this
(FullOpts)</summary>
<div style="margin-left:1em">
No diffs found?
</div></details>
<details>
<summary>+0 (0.00%) : 18873.dasm -
System.Threading.Tasks.Task:get_CompletedTask() (FullOpts)</summary>
<div style="margin-left:1em">
No diffs found?
</div></details>
</div></details>
</div></details>
<details>
<summary>Details</summary>
<div style="margin-left:1em">
#### Size improvements/regressions per collection
|Collection|Contexts with diffs|Improvements|Regressions|Same
size|Improvements (bytes)|Regressions (bytes)|
|---|--:|--:|--:|--:|--:|--:|
|libraries_tests_no_tiered_compilation.run.linux.arm64.Release.mch|11|<span
style="color:green">10</span>|<span style="color:red">0</span>|<span
style="color:blue">1</span>|<span style="color:green">-40</span>|<span
style="color:red">+0</span>|
|benchmarks.run.linux.arm64.checked.mch|1|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">1</span>|<span style="color:green">-0</span>|<span
style="color:red">+0</span>|
|smoke_tests.nativeaot.linux.arm64.checked.mch|4|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">4</span>|<span style="color:green">-0</span>|<span
style="color:red">+0</span>|
||16|<span style="color:green">10</span>|<span
style="color:red">0</span>|<span style="color:blue">6</span>|<span
style="color:green">-40</span>|<span style="color:red">+0</span>|
---
#### PerfScore improvements/regressions per collection
|Collection|Contexts with diffs|Improvements|Regressions|Same
PerfScore|Improvements (PerfScore)|Regressions (PerfScore)|PerfScore
Overall in FullOpts|
|---|--:|--:|--:|--:|--:|--:|--:|
|libraries_tests_no_tiered_compilation.run.linux.arm64.Release.mch|11|<span
style="color:green">10</span>|<span style="color:red">0</span>|<span
style="color:blue">1</span>|<span
style="color:green">-0.10%</span>|0.00%|<span
style="color:green">-0.0000%</span>|
|benchmarks.run.linux.arm64.checked.mch|1|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">1</span>|0.00%|0.00%|0.0000%|
|smoke_tests.nativeaot.linux.arm64.checked.mch|4|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">4</span>|0.00%|0.00%|0.0000%|
---
#### Context information
|Collection|Diffed contexts|MinOpts|FullOpts|Missed, base|Missed, diff|
|---|--:|--:|--:|--:|--:|
|libraries_tests_no_tiered_compilation.run.linux.arm64.Release.mch|354,001|23,273|330,728|0
(0.00%)|0 (0.00%)|
|benchmarks.run.linux.arm64.checked.mch|63,204|3,337|59,867|0 (0.00%)|0
(0.00%)|
|smoke_tests.nativeaot.linux.arm64.checked.mch|18,890|8|18,882|0
(0.00%)|0 (0.00%)|
||436,095|26,618|409,477|0 (0.00%)|0 (0.00%)|
---
#### jit-analyze output
<details>
<summary>libraries_tests_no_tiered_compilation.run.linux.arm64.Release.mch</summary>
<div style="margin-left:1em">
```
Summary of Code Size diffs:
(Lower is better)
Total bytes of base: 183146276 (overridden on cmd)
Total bytes of diff: 183146236 (overridden on cmd)
Total bytes of delta: -40 (-0.00 % of base)
diff is an improvement.
relative diff is an improvement.
```
<details>
<summary>Detail diffs</summary>
```
Top file improvements (bytes):
-4 : 162916.dasm (-0.242% of base)
-4 : 141852.dasm (-0.162% of base)
-4 : 141855.dasm (-0.158% of base)
-4 : 141861.dasm (-0.201% of base)
-4 : 162917.dasm (-0.269% of base)
-4 : 142473.dasm (-1.266% of base)
-4 : 142389.dasm (-0.182% of base)
-4 : 162915.dasm (-0.264% of base)
-4 : 162918.dasm (-0.185% of base)
-4 : 106573.dasm (-0.022% of base)
10 total files with Code Size differences (10 improved, 0 regressed), 1 unchanged.
Top method improvements (bytes):
-4 (-0.022% of base) : 106573.dasm - System.Data.Tests.DataTableTest2:Select_ByFilter():this (FullOpts)
-4 (-1.266% of base) : 142473.dasm - System.IO.Pipelines.Tests.BufferSegmentPoolTest:GetSegments(System.IO.Pipelines.ReadResult):System.Collections.Generic.List`1[System.Buffers.ReadOnlySequenceSegment`1[byte]] (FullOpts)
-4 (-0.182% of base) : 142389.dasm - System.IO.Pipelines.Tests.PipelineReaderWriterFacts:ResetAfterCompleteReaderAndWriterWithoutAdvancingClearsEverything():this (FullOpts)
-4 (-0.162% of base) : 141852.dasm - System.IO.Pipelines.Tests.PipePoolTests:GetMemoryAtMaxPoolSizeAllocatesFromPool():this (FullOpts)
-4 (-0.158% of base) : 141855.dasm - System.IO.Pipelines.Tests.PipePoolTests:GetMemoryOverMaxPoolSizeAllocatesArray():this (FullOpts)
-4 (-0.201% of base) : 141861.dasm - System.IO.Pipelines.Tests.PipePoolTests:WritesToArrayPoolByDefault():this (FullOpts)
-4 (-0.242% of base) : 162916.dasm - System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_IMemoryList_MultiBlock():this (FullOpts)
-4 (-0.185% of base) : 162918.dasm - System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_IMemoryList_SingleBlock():this (FullOpts)
-4 (-0.264% of base) : 162915.dasm - System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory_String():this (FullOpts)
-4 (-0.269% of base) : 162917.dasm - System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory():this (FullOpts)
Top method improvements (percentages):
-4 (-1.266% of base) : 142473.dasm - System.IO.Pipelines.Tests.BufferSegmentPoolTest:GetSegments(System.IO.Pipelines.ReadResult):System.Collections.Generic.List`1[System.Buffers.ReadOnlySequenceSegment`1[byte]] (FullOpts)
-4 (-0.269% of base) : 162917.dasm - System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory():this (FullOpts)
-4 (-0.264% of base) : 162915.dasm - System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_Memory_String():this (FullOpts)
-4 (-0.242% of base) : 162916.dasm - System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_IMemoryList_MultiBlock():this (FullOpts)
-4 (-0.201% of base) : 141861.dasm - System.IO.Pipelines.Tests.PipePoolTests:WritesToArrayPoolByDefault():this (FullOpts)
-4 (-0.185% of base) : 162918.dasm - System.Memory.Tests.ReadOnlySequenceTryGetTests:Ctor_IMemoryList_SingleBlock():this (FullOpts)
-4 (-0.182% of base) : 142389.dasm - System.IO.Pipelines.Tests.PipelineReaderWriterFacts:ResetAfterCompleteReaderAndWriterWithoutAdvancingClearsEverything():this (FullOpts)
-4 (-0.162% of base) : 141852.dasm - System.IO.Pipelines.Tests.PipePoolTests:GetMemoryAtMaxPoolSizeAllocatesFromPool():this (FullOpts)
-4 (-0.158% of base) : 141855.dasm - System.IO.Pipelines.Tests.PipePoolTests:GetMemoryOverMaxPoolSizeAllocatesArray():this (FullOpts)
-4 (-0.022% of base) : 106573.dasm - System.Data.Tests.DataTableTest2:Select_ByFilter():this (FullOpts)
10 total methods with Code Size differences (10 improved, 0 regressed).
```
</details>
--------------------------------------------------------------------------------
</div></details>
<details>
<summary>benchmarks.run.linux.arm64.checked.mch</summary>
<div style="margin-left:1em">
```
Summary of Code Size diffs:
(Lower is better)
Total bytes of base: 21285888 (overridden on cmd)
Total bytes of diff: 21285888 (overridden on cmd)
Total bytes of delta: 0 (0.00 % of base)
```
<details>
<summary>Detail diffs</summary>
```
0 total files with Code Size differences (0 improved, 0 regressed), 1 unchanged.
0 total methods with Code Size differences (0 improved, 0 regressed).
```
</details>
--------------------------------------------------------------------------------
</div></details>
</div></details>
x64 asmdiffs
Diffs are based on <span style="color:#1460aa">2,787,549</span> contexts
(<span style="color:#1460aa">1,078,277</span> MinOpts, <span
style="color:#1460aa">1,709,272</span> FullOpts).
<details>
<summary>Overall (<span style="color:green">-116</span> bytes)</summary>
<div style="margin-left:1em">
|Collection|Base size (bytes)|Diff size (bytes)|PerfScore in Diffs
|---|--:|--:|--:|
|coreclr_tests.run.linux.x64.checked.mch|305,501,642|<span
style="color:green">-110</span>|<span
style="color:green">-14.87%</span>|
|libraries_tests_no_tiered_compilation.run.linux.x64.Release.mch|157,729,192|<span
style="color:green">-2</span>|<span style="color:green">-0.01%</span>|
|libraries_tests.run.linux.x64.Release.mch|392,784,680|<span
style="color:green">-4</span>|<span style="color:green">-0.01%</span>|
</div></details>
<details>
<summary>MinOpts (<span style="color:green">-14</span> bytes)</summary>
<div style="margin-left:1em">
|Collection|Base size (bytes)|Diff size (bytes)|PerfScore in Diffs
|---|--:|--:|--:|
|coreclr_tests.run.linux.x64.checked.mch|197,469,852|<span
style="color:green">-10</span>|<span style="color:green">-1.28%</span>|
|libraries_tests.run.linux.x64.Release.mch|215,792,030|<span
style="color:green">-4</span>|<span style="color:green">-0.01%</span>|
</div></details>
<details>
<summary>FullOpts (<span style="color:green">-102</span>
bytes)</summary>
<div style="margin-left:1em">
|Collection|Base size (bytes)|Diff size (bytes)|PerfScore in Diffs
|---|--:|--:|--:|
|coreclr_tests.run.linux.x64.checked.mch|108,031,790|<span
style="color:green">-100</span>|<span
style="color:green">-16.74%</span>|
|libraries_tests_no_tiered_compilation.run.linux.x64.Release.mch|146,383,976|<span
style="color:green">-2</span>|<span style="color:green">-0.01%</span>|
</div></details>
<details>
<summary>Example diffs</summary>
<div style="margin-left:1em">
<details>
<summary>coreclr_tests.run.linux.x64.checked.mch</summary>
<div style="margin-left:1em">
<details>
<summary><span style="color:green">-8</span> (<span
style="color:green">-29.63%</span>) : 199901.dasm -
TestNeg.Program:NegsBinOpSingleLine(int,int):bool (FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -18,23 +18,19 @@ G_M18888_IG01: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref,
;; size=0 bbWeight=1 PerfScore 0.00
G_M18888_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
sar edi, 1
- mov eax, edi
- neg eax
setne al
movzx rax, al
- add esi, esi
- mov ecx, esi
- neg ecx
+ shl esi, 1
setne cl
movzx rcx, cl
or eax, ecx
- ;; size=26 bbWeight=1 PerfScore 4.50
+ ;; size=18 bbWeight=1 PerfScore 3.75
G_M18888_IG03: ; bbWeight=1, epilog, nogc, extend
ret ;; size=1 bbWeight=1 PerfScore 1.00
; END METHOD TestNeg.Program:NegsBinOpSingleLine(int,int):bool
-; Total bytes of code 27, prolog size 0, PerfScore 5.50, instruction count 12, allocated bytes for code 27 (MethodHash=d08ab637) for method TestNeg.Program:NegsBinOpSingleLine(int,int):bool (FullOpts)
+; Total bytes of code 19, prolog size 0, PerfScore 4.75, instruction count 8, allocated bytes for code 19 (MethodHash=d08ab637) for method TestNeg.Program:NegsBinOpSingleLine(int,int):bool (FullOpts)
; ============================================================
Unwind Info:
```
</div></details>
<details>
<summary><span style="color:green">-7</span> (<span
style="color:green">-29.17%</span>) : 199894.dasm -
TestNeg.Program:NegsLSR(uint):int (FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -16,20 +16,17 @@
G_M6300_IG01: ; bbWeight=0.50, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref, nogc <-- Prolog IG
;; size=0 bbWeight=0.50 PerfScore 0.00
G_M6300_IG02: ; bbWeight=0.50, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
+ mov eax, -1
+ mov ecx, 1
shr edi, 3
- mov eax, edi
- mov ecx, -1
- mov edx, 1
- neg rax
- mov eax, edx
- cmove eax, ecx
- ;; size=23 bbWeight=0.50 PerfScore 1.00
+ cmovne eax, ecx
+ ;; size=16 bbWeight=0.50 PerfScore 0.62
G_M6300_IG03: ; bbWeight=0.50, epilog, nogc, extend
ret ;; size=1 bbWeight=0.50 PerfScore 0.50
; END METHOD TestNeg.Program:NegsLSR(uint):int
-; Total bytes of code 24, prolog size 0, PerfScore 1.50, instruction count 8, allocated bytes for code 24 (MethodHash=2a8ee763) for method TestNeg.Program:NegsLSR(uint):int (FullOpts)
+; Total bytes of code 17, prolog size 0, PerfScore 1.12, instruction count 5, allocated bytes for code 17 (MethodHash=2a8ee763) for method TestNeg.Program:NegsLSR(uint):int (FullOpts)
; ============================================================
Unwind Info:
```
</div></details>
<details>
<summary><span style="color:green">-7</span> (<span
style="color:green">-29.17%</span>) : 199896.dasm -
TestNeg.Program:NegsLargeShift(uint):int (FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -16,20 +16,17 @@
G_M11276_IG01: ; bbWeight=0.50, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref, nogc <-- Prolog IG
;; size=0 bbWeight=0.50 PerfScore 0.00
G_M11276_IG02: ; bbWeight=0.50, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
+ mov eax, -1
+ mov ecx, 1
shl edi, 4
- mov eax, edi
- mov ecx, -1
- mov edx, 1
- neg rax
- mov eax, edx
- cmove eax, ecx
- ;; size=23 bbWeight=0.50 PerfScore 1.00
+ cmovne eax, ecx
+ ;; size=16 bbWeight=0.50 PerfScore 0.62
G_M11276_IG03: ; bbWeight=0.50, epilog, nogc, extend
ret ;; size=1 bbWeight=0.50 PerfScore 0.50
; END METHOD TestNeg.Program:NegsLargeShift(uint):int
-; Total bytes of code 24, prolog size 0, PerfScore 1.50, instruction count 8, allocated bytes for code 24 (MethodHash=43eed3f3) for method TestNeg.Program:NegsLargeShift(uint):int (FullOpts)
+; Total bytes of code 17, prolog size 0, PerfScore 1.12, instruction count 5, allocated bytes for code 17 (MethodHash=43eed3f3) for method TestNeg.Program:NegsLargeShift(uint):int (FullOpts)
; ============================================================
Unwind Info:
```
</div></details>
<details>
<summary><span style="color:green">-5</span> (<span
style="color:green">-1.71%</span>) : 531325.dasm -
ILGEN_CLASS:ILGEN_METHOD(bool,char,short,int):char (Tier0)</summary>
<div style="margin-left:1em">
```diff
@@ -74,16 +74,14 @@ G_M28265_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref,
mov qword ptr [rbp-0x40], rdx
mov rax, qword ptr [rbp-0x40]
mov qword ptr [rbp-0x48], rax
- mov eax, dword ptr [rbp-0x28]
- neg rax
- test rax, rax
+ cmp dword ptr [rbp-0x28], 0
jne SHORT G_M28265_IG03
mov eax, dword ptr [rbp-0x18]
cmp eax, 255
ja SHORT G_M28265_IG06
mov eax, eax
mov byte ptr [rbp-0x04], al
- ;; size=182 bbWeight=1 PerfScore 117.08
+ ;; size=177 bbWeight=1 PerfScore 117.58
G_M28265_IG03: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref, isz
mov eax, dword ptr [rbp-0x10]
cmp rax, qword ptr [rbp-0x48]
@@ -116,7 +114,7 @@ RWD16 dq	8000000000000000h	; -0
RWD24 dd	4F0BD98Fh ; 2.34629e+09
-; Total bytes of code 293, prolog size 31, PerfScore 147.42, instruction count 75, allocated bytes for code 293 (MethodHash=d26f9196) for method ILGEN_CLASS:ILGEN_METHOD(bool,char,short,int):char (Tier0)
+; Total bytes of code 288, prolog size 31, PerfScore 147.92, instruction count 73, allocated bytes for code 288 (MethodHash=d26f9196) for method ILGEN_CLASS:ILGEN_METHOD(bool,char,short,int):char (Tier0)
; ============================================================
Unwind Info:
```
</div></details>
<details>
<summary><span style="color:green">-2</span> (<span
style="color:green">-4.17%</span>) : 181410.dasm -
ldc_neg_i4._neg:i4_3(int,int):int (MinOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -30,18 +30,17 @@ G_M1458_IG03: ; bbWeight=0.50, gcrefRegs=0000 {}, byrefRegs=0000 {}, byre
;; size=5 bbWeight=0.50 PerfScore 0.50
G_M1458_IG04: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
xor eax, eax
- neg eax
test eax, eax
sete al
movzx rax, al
- ;; size=12 bbWeight=1 PerfScore 2.00
+ ;; size=10 bbWeight=1 PerfScore 1.75
G_M1458_IG05: ; bbWeight=1, epilog, nogc, extend
add rsp, 16
pop rbp
ret ;; size=6 bbWeight=1 PerfScore 1.75
-; Total bytes of code 48, prolog size 16, PerfScore 12.00, instruction count 16, allocated bytes for code 48 (MethodHash=0125fa4d) for method ldc_neg_i4._neg:i4_3(int,int):int (MinOpts)
+; Total bytes of code 46, prolog size 16, PerfScore 11.75, instruction count 15, allocated bytes for code 46 (MethodHash=0125fa4d) for method ldc_neg_i4._neg:i4_3(int,int):int (MinOpts)
; ============================================================
Unwind Info:
```
</div></details>
<details>
<summary><span style="color:green">-3</span> (<span
style="color:green">-5.77%</span>) : 181421.dasm -
ldc_neg_i8._neg:i8_3(long,long):int (MinOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -30,18 +30,17 @@ G_M18290_IG03: ; bbWeight=0.50, gcrefRegs=0000 {}, byrefRegs=0000 {}, byr
;; size=5 bbWeight=0.50 PerfScore 0.50
G_M18290_IG04: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
xor eax, eax
- neg rax
test rax, rax
sete al
movzx rax, al
- ;; size=14 bbWeight=1 PerfScore 2.00
+ ;; size=11 bbWeight=1 PerfScore 1.75
G_M18290_IG05: ; bbWeight=1, epilog, nogc, extend
add rsp, 16
pop rbp
ret ;; size=6 bbWeight=1 PerfScore 1.75
-; Total bytes of code 52, prolog size 18, PerfScore 12.00, instruction count 16, allocated bytes for code 52 (MethodHash=ff46b88d) for method ldc_neg_i8._neg:i8_3(long,long):int (MinOpts)
+; Total bytes of code 49, prolog size 18, PerfScore 11.75, instruction count 15, allocated bytes for code 49 (MethodHash=ff46b88d) for method ldc_neg_i8._neg:i8_3(long,long):int (MinOpts)
; ============================================================
Unwind Info:
```
</div></details>
</div></details>
<details>
<summary>libraries_tests_no_tiered_compilation.run.linux.x64.Release.mch</summary>
<div style="margin-left:1em">
<details>
<summary><span style="color:green">-2</span> (<span
style="color:green">-0.01%</span>) : 124444.dasm -
System.Data.Tests.DataTableTest2:Select_ByFilter():this
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -3246,7 +3246,6 @@ G_M43941_IG102: ; bbWeight=1, gcVars=000000000000000000000000000000000000
G_M43941_IG103: ; bbWeight=4, gcrefRegs=F009 {rax rbx r12 r13 r14 r15}, byrefRegs=0000 {}, byref, isz
mov esi, dword ptr [rbp-0x30]
sub esi, dword ptr [rax+0x08]
- neg esi
je G_M43941_IG96
inc dword ptr [r13+0x14]
mov rdi, gword ptr [r13+0x08]
@@ -3254,7 +3253,7 @@ G_M43941_IG103: ; bbWeight=4, gcrefRegs=F009 {rax rbx r12 r13 r14 r15}, b
mov esi, dword ptr [r13+0x10]
cmp dword ptr [rdi+0x08], esi
jbe SHORT G_M43941_IG106
- ;; size=31 bbWeight=4 PerfScore 65.00
+ ;; size=29 bbWeight=4 PerfScore 64.00
G_M43941_IG104: ; bbWeight=3.05, gcVars=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 {V06}, gcrefRegs=F088 {rbx rdi r12 r13 r14 r15}, byrefRegs=0000 {}, gcvars, byref
; gcrRegs -[rax]
; GC ptr vars -{V75}
@@ -6658,7 +6657,7 @@ RWD40 dq	4034000000000000h	; 20
RWD48 dq	4039000000000000h	; 25
-; Total bytes of code 14316, prolog size 28, PerfScore 7866.28, instruction count 3034, allocated bytes for code 14316 (MethodHash=c958545a) for method System.Data.Tests.DataTableTest2:Select_ByFilter():this (FullOpts)
+; Total bytes of code 14314, prolog size 28, PerfScore 7865.28, instruction count 3033, allocated bytes for code 14314 (MethodHash=c958545a) for method System.Data.Tests.DataTableTest2:Select_ByFilter():this (FullOpts)
; ============================================================
Unwind Info:
```
</div></details>
</div></details>
<details>
<summary>libraries_tests.run.linux.x64.Release.mch</summary>
<div style="margin-left:1em">
<details>
<summary><span style="color:green">-4</span> (<span
style="color:green">-0.03%</span>) : 314396.dasm -
System.Data.Tests.DataTableTest2:Select_ByFilter():this (Instrumented
Tier0)</summary>
<div style="margin-left:1em">
```diff
@@ -2199,13 +2199,11 @@ G_M43941_IG57: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
; gcr arg pop 0
mov ecx, dword ptr [rbp-0x240]
sub ecx, dword ptr [rax]
- mov eax, ecx
- ; byrRegs -[rax]
- neg eax
- test eax, eax
+ test ecx, ecx
je G_M43941_IG56
mov rdi, 0xD1FFAB1E
call CORINFO_HELP_COUNTPROFILE32
+ ; byrRegs -[rax]
; gcr arg pop 0
mov rdi, gword ptr [rbp-0x50]
; gcrRegs +[rdi]
@@ -2215,7 +2213,7 @@ G_M43941_IG57: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
call [<unknown method>]
; gcrRegs -[rsi rdi]
; gcr arg pop 0
- ;; size=309 bbWeight=1 PerfScore 58.00
+ ;; size=305 bbWeight=1 PerfScore 57.50
G_M43941_IG58: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref, isz
mov eax, dword ptr [rbp-0x5E0]
dec eax
@@ -5412,7 +5410,7 @@ RWD08 dq	4034000000000000h	; 20
RWD16 dq	4039000000000000h	; 25
-; Total bytes of code 15982, prolog size 67, PerfScore 3425.70, instruction count 2755, allocated bytes for code 15982 (MethodHash=c958545a) for method System.Data.Tests.DataTableTest2:Select_ByFilter():this (Instrumented Tier0)
+; Total bytes of code 15978, prolog size 67, PerfScore 3425.20, instruction count 2753, allocated bytes for code 15978 (MethodHash=c958545a) for method System.Data.Tests.DataTableTest2:Select_ByFilter():this (Instrumented Tier0)
; ============================================================
Unwind Info:
```
</div></details>
</div></details>
</div></details>
<details>
<summary>Details</summary>
<div style="margin-left:1em">
#### Size improvements/regressions per collection
|Collection|Contexts with diffs|Improvements|Regressions|Same
size|Improvements (bytes)|Regressions (bytes)|
|---|--:|--:|--:|--:|--:|--:|
|benchmarks.run.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-0</span>|<span
style="color:red">+0</span>|
|benchmarks.run_pgo.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-0</span>|<span
style="color:red">+0</span>|
|benchmarks.run_pgo_optrepeat.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-0</span>|<span
style="color:red">+0</span>|
|coreclr_tests.run.linux.x64.checked.mch|23|<span
style="color:green">23</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-110</span>|<span
style="color:red">+0</span>|
|libraries.crossgen2.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-0</span>|<span
style="color:red">+0</span>|
|libraries.pmi.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-0</span>|<span
style="color:red">+0</span>|
|libraries_tests_no_tiered_compilation.run.linux.x64.Release.mch|1|<span
style="color:green">1</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-2</span>|<span
style="color:red">+0</span>|
|libraries_tests.run.linux.x64.Release.mch|1|<span
style="color:green">1</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-4</span>|<span
style="color:red">+0</span>|
|realworld.run.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-0</span>|<span
style="color:red">+0</span>|
|smoke_tests.nativeaot.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-0</span>|<span
style="color:red">+0</span>|
||25|<span style="color:green">25</span>|<span
style="color:red">0</span>|<span style="color:blue">0</span>|<span
style="color:green">-116</span>|<span style="color:red">+0</span>|
---
#### PerfScore improvements/regressions per collection
|Collection|Contexts with diffs|Improvements|Regressions|Same
PerfScore|Improvements (PerfScore)|Regressions (PerfScore)|PerfScore
Overall in FullOpts|
|---|--:|--:|--:|--:|--:|--:|--:|
|benchmarks.run.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|0.00%|0.00%|0.0000%|
|benchmarks.run_pgo.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|0.00%|0.00%|0.0000%|
|benchmarks.run_pgo_optrepeat.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|0.00%|0.00%|0.0000%|
|coreclr_tests.run.linux.x64.checked.mch|23|<span
style="color:green">22</span>|<span style="color:red">1</span>|<span
style="color:blue">0</span>|<span
style="color:green">-15.50%</span>|<span
style="color:red">+0.34%</span>|<span
style="color:green">-0.0017%</span>|
|libraries.crossgen2.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|0.00%|0.00%|0.0000%|
|libraries.pmi.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|0.00%|0.00%|0.0000%|
|libraries_tests_no_tiered_compilation.run.linux.x64.Release.mch|1|<span
style="color:green">1</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span
style="color:green">-0.01%</span>|0.00%|<span
style="color:green">-0.0000%</span>|
|libraries_tests.run.linux.x64.Release.mch|1|<span
style="color:green">1</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span
style="color:green">-0.01%</span>|0.00%|0.0000%|
|realworld.run.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|0.00%|0.00%|0.0000%|
|smoke_tests.nativeaot.linux.x64.checked.mch|0|<span
style="color:green">0</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|0.00%|0.00%|0.0000%|
---
#### Context information
|Collection|Diffed contexts|MinOpts|FullOpts|Missed, base|Missed, diff|
|---|--:|--:|--:|--:|--:|
|benchmarks.run.linux.x64.checked.mch|75,913|2,972|72,941|0 (0.00%)|0
(0.00%)|
|benchmarks.run_pgo.linux.x64.checked.mch|122,785|86,206|36,579|0
(0.00%)|0 (0.00%)|
|benchmarks.run_pgo_optrepeat.linux.x64.checked.mch|76,998|2,939|74,059|0
(0.00%)|0 (0.00%)|
|coreclr_tests.run.linux.x64.checked.mch|577,098|358,595|218,503|0
(0.00%)|0 (0.00%)|
|libraries.crossgen2.linux.x64.checked.mch|269,385|20|269,365|0
(0.00%)|0 (0.00%)|
|libraries.pmi.linux.x64.checked.mch|354,706|8|354,698|0 (0.00%)|0
(0.00%)|
|libraries_tests_no_tiered_compilation.run.linux.x64.Release.mch|387,764|23,607|364,157|0
(0.00%)|0 (0.00%)|
|libraries_tests.run.linux.x64.Release.mch|862,114|603,896|258,218|0
(0.00%)|0 (0.00%)|
|realworld.run.linux.x64.checked.mch|29,264|21|29,243|0 (0.00%)|0
(0.00%)|
|smoke_tests.nativeaot.linux.x64.checked.mch|31,522|13|31,509|0
(0.00%)|0 (0.00%)|
||2,787,549|1,078,277|1,709,272|0 (0.00%)|0 (0.00%)|
---
#### jit-analyze output
</div></details>
ManickaP pushed a commit that referenced this pull request May 15, 2026
…128163)
> [!NOTE]
> This PR was authored with assistance from GitHub Copilot.
Fixesdotnet#128044.
## Problem
createdump SIGSEGVs on Linux when generating a Heap-type minidump for a
process running interpreted code. The crash reproduces locally with the
`InterpreterStack` DumpTests debuggee and matches the CI failure that
prompted `<DumpTypes>Full</DumpTypes>` to be added as a temporary
workaround.
The faulting backtrace is:
```
#0 Thread::IsAddressInStack threads.cpp:6741
#1 Thread::EnumMemoryRegionsWorker threads.cpp:6909 (calls IsAddressInStack(currentSP))
#2 Thread::EnumMemoryRegions threads.cpp
#3 ThreadStore::EnumMemoryRegions
#4 ClrDataAccess::EnumMemDumpAllThreadsStack
#5 ClrDataAccess::EnumMemoryRegionsWorkerHeap (HEAP2-only path)
```
## Root cause
`Thread::m_pInterpThreadContext` was declared as a raw
`InterpThreadContext *`. In non-DAC code that's a normal host pointer,
but in
DAC mode the field's value is a target-process address. When
`IsAddressInStack` (a DAC-callable helper) dereferenced
`m_pInterpThreadContext->pStackStart` it read from a target-process
address
as if it were a host address, which faults inside createdump.
## Fix
Change the field type to `PTR_InterpThreadContext` (DPTR), matching the
treatment of other Thread fields like `m_pFrame`. In non-DAC builds
`DPTR(T)` is just `T*`, so there is no overhead or behavior change. In
DAC
builds the read goes through `__DPtr<T>` and marshals correctly from the
target.
Also remove the `<DumpTypes>Full</DumpTypes>` workaround on the
`InterpreterStack` DumpTests debuggee so the Heap path that originally
failed is exercised again.
## Validation
Locally reproduced the original SIGSEGV on Linux x64 with the auto-dump
mechanism (`DOTNET_DbgMiniDumpType=2` + `DOTNET_Interpreter=MethodA`)
running the `InterpreterStack` debuggee. With this fix applied,
createdump
produces a complete Heap dump (~74 MB) instead of crashing.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ManickaP pushed a commit that referenced this pull request Jun 4, 2026
An Android production app reported a native abort while building an
X.509 chain on arm64. The available tombstone snippet showed the process
aborting in `AndroidCryptoNative_X509ChainBuild` from `pal_x509chain.c`,
with the native guard reporting that parameter `ctx` was not a valid
pointer. The report did not include a repro or full tombstone, but the
observed failure mode means managed code reached the native build entry
point with a null `X509ChainContext*`.
```
Thread
/__w/1/s/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c:113 (AndroidCryptoNative_X509ChainBuild): Parameter 'ctx' must be a valid pointer
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 31609 >>> com.app.name <<<
backtrace:
#00 pc 0x000000000002232c /system/lib64/libc.so (abort+116)
#1 pc 0x0000000000021fe8 [removed]-KwPZdoEumri00C7kBm3pQw==/lib/arm64/libSystem.Security.Cryptography.Native.Android.so
#2 pc 0x00000000000220b0 [removed]-KwPZdoEumri00C7kBm3pQw==/lib/arm64/libSystem.Security.Cryptography.Native.Android.so (AndroidCryptoNative_X509ChainBuild+88)
#3 pc 0x000000000000cfcc
```
`X509ChainContext` is created by
`AndroidCryptoNative_X509ChainCreateContext`. That initialization can
fail if Android certificate store setup or PKIX parameter construction
throws, or if required JNI global references cannot be created.
Previously, the managed Android chain path stored the returned
`SafeHandle` without checking whether context creation failed, so a
later build could pass a null native context to
`AndroidCryptoNative_X509ChainBuild` and terminate the app process.
This change makes context creation fail gracefully:
- The native create path checks Java exceptions around object creation
and method calls more consistently.
- Partial native contexts are destroyed if global-reference creation
fails.
- The Android interop wrapper checks the returned chain context
immediately, including a null safe-handle return, and throws
`CryptographicException` if initialization failed.
No regression test is included because the reliable failure modes depend
on Android platform/provider state or artificial fault injection, and a
test hook would be fragile and not representative.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Kevin Jones <kevin@vcsjones.com>
ManickaP pushed a commit that referenced this pull request Jun 30, 2026
…on ARM32 (dotnet#129672)
Enables the cDAC GC stress verification leg on `linux_arm` (arm32) in
`runtime-diagnostics.yml`. While bringing arm32 online surfaced a
long-standing type confusion in the cDAC managed side that this PR also
fixes.
## Pipeline change
Adds `linux_arm` to the `cdacStressPlatforms` default in
[`eng/pipelines/runtime-diagnostics.yml`](https://github.com/dotnet/runtime/blob/main/eng/pipelines/runtime-diagnostics.yml).
The Helix queue mapping already existed in
`prepare-cdac-stress-helix-steps.yml` (`helix_linux_arm32_oldest`), so
this is a one-line enablement.
## arm32 failure surfaced by enabling the leg
First run on arm32 failed every verification with the same shape - e.g.
`DynamicMethods`: `1694 verifications (18 pass / 1676 fail / 0
known-issue)`, with every frame appearing duplicated at consecutive IPs
differing by 1:
```
Frame #0 <0xea89cc4e> MISMATCH cDAC=0 RT=2 ONLY(RT)
Frame #1 <0xea89cc4f> MISMATCH cDAC=2 RT=0 ONLY(cDAC) <-- same refs, IP|1
```
**Root cause:** ARM32 control PCs carry the Thumb bit (LSB) to indicate
execution mode. The native runtime applies `PCODEToPINSTR`
([utilcode.h](https://github.com/dotnet/runtime/blob/main/src/coreclr/inc/utilcode.h#L119))
before reporting an IP as `StackRefData.Source`:
- Legacy DAC: `src/coreclr/debug/daccess/daccess.cpp:7558` -- `dsc->pc =
PCODEToPINSTR(GetControlPC(pRD))`
- In-process stress oracle: `src/coreclr/vm/cdacstress.cpp:781-782` --
same masking
The cDAC stored raw PCODE in `GcScanContext.InstructionPointer` and
emitted it as the Source, so every cDAC ref got keyed at `IP|1` while
the runtime reported at `IP`.
## Fix: type the IP/return-address surface as `TargetCodePointer`
Rather than masking the Thumb bit ad-hoc at one consumer site, the
proper fix is to **type these values correctly throughout the stack** so
the compiler stops the next person from mixing code pointers and data
pointers:
**Managed contract surface promoted `TargetPointer` →
`TargetCodePointer`:**
- `IPlatformContext.InstructionPointer` and every per-arch impl
(`X86Context`, `AMD64Context`, `ARMContext`, `ARM64Context`,
`LoongArch64Context`, `RISCV64Context`)
- `IPlatformAgnosticContext.InstructionPointer` and
`ContextHolder<T>.InstructionPointer`
- `IStackWalk.GetInstructionPointer`,
`FrameIterator.GetCurrentReturnAddress`, `FrameHelpers.GetReturnAddress`
- `[Field]` properties on `Data.TransitionBlock.ReturnAddress`,
`Data.HijackFrame.ReturnAddress`,
`Data.SoftwareExceptionFrame.ReturnAddress`,
`Data.TailCallFrame.ReturnAddress`,
`Data.InlinedCallFrame.CallerReturnAddress`
**Native data-descriptor changes**
(`src/coreclr/vm/datadescriptor/datadescriptor.inc`) - the corresponding
5 `CDAC_TYPE_FIELD` declarations switched from `T_POINTER` to
`TYPE(CodePointer)` so the descriptor's advertised type matches what the
field actually holds. Each was verified to carry the Thumb bit on ARM32:
| Field | Evidence |
|---|---|
| `TransitionBlock::m_ReturnAddress` | `callingconvention.h:140-148` -
**explicitly aliased** to `{r4..r11, lr}` (saved LR = PC\|1) |
| `InlinedCallFrame::m_pCallerReturnAddress` | ARM asm `str lr, [...]`
(`pinvokestubs.S:96, 182`); read back as PCODE (`stubs.cpp:1348-1349`) |
| `HijackFrame::m_ReturnAddress` | ctor sourced from on-stack saved LR
(`threadsuspend.cpp:4546`) |
| `SoftwareExceptionFrame::m_ReturnAddress` | copied straight into ARM
`Pc` register field (`excep.cpp:10474-10475`) |
| `TailCallFrame::m_ReturnAddress` | x86-only (descriptor guarded by
`TARGET_X86`); `CodePointer` still semantically correct |
**Conversion lives in one place:** `GcScanContext.SetSource` calls
`CodePointerUtils.AddressFromCodePointer` (the existing single source of
truth for PCODE → PINSTR on a target) when populating
`StackRefData.Source`. Other consumers that want code pointers
(`IsManaged`, `IsInterpreterCode`, `_eman.GetCodeBlockHandle`) now
receive `TargetCodePointer` directly. The few places that need raw data
addresses (AMD64 unwinder's `controlPC` arithmetic with `imageBase`,
x64-only `SOSDacImpl.GetJumpThunkTarget`) call `.AsTargetPointer`
explicitly.
## Validation
- `./build.cmd clr.runtime -c Release` succeeded; data descriptor
regenerated with `TYPE(CodePointer)` fields.
- cDAC unit tests: `Passed: 2571, Failed: 0, Skipped: 16`.
- CI: every `CdacBuild`, `CdacDumpTest`, and `CdacStressTest` leg green
- **including the new `CdacStressTest linux-arm` leg** that surfaced the
bug, plus existing `linux-arm64`, `linux-x64`, `windows-arm64`,
`windows-x64` legs.
## Notes for reviewers
- `IStackWalk` and `IPlatformAgnosticContext` live in
`Microsoft.Diagnostics.DataContractReader.Abstractions`. Per the cDAC
`API Review` guidance
([`cdac.instructions.md`](https://github.com/dotnet/runtime/blob/main/.github/instructions/cdac.instructions.md#api-review-net-11-dev-branches-only)),
implementations of `IContract` are not under formal API review on .NET
11 dev branches, and the contract assemblies are internal/unstable.
Changing the IP/return-address types is intentional and not a
breaking-change event.
- `CodePointerUtils.AddressFromCodePointer` already throws
`NotImplementedException` for `HasArm64PtrAuth`; when that's wired up,
the single conversion in `SetSource` picks it up with no further
changes.
> [!NOTE]
> This PR was authored with assistance from GitHub Copilot.
---------
Co-authored-by: Max Charlamb <maxcharlamb@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ManickaP pushed a commit that referenced this pull request Jun 30, 2026
…dotnet#129280) (dotnet#129591)
## Problem
`Wasm.Build.Tests.WasmTemplateTests.TypeScriptDefinitionsCopiedToWwwrootOnBuild(config:
Debug, emitTypeScriptDts: True)` fails its `dotnet build -question`
rebuild check with:
```
MSBUILD : error : Building target "_BuildCopyStaticWebAssetsPreserveNewest" partially,
because some output files are out of date with respect to their input files.
[_BuildStaticWebAssetsPreserveNewest:
Input = obj\Debug\net11.0\compressed\{hash}-{0}-{fp}-{fp}.gz,
Output = bin\Debug\net11.0\wwwroot\_framework\dotnet.{fp}.js.gz]
Input file is newer than output file.
```
This is the same family of bug as dotnet#129280 (different surface: upstream
variant where MSBuild flags `_WriteBuildWasmBootJsonFile` itself as
stale; ours is the downstream cascade through compression).
## Root cause
Binlog analysis:
1. `_WriteBuildWasmBootJsonFile` runs `GenerateWasmBootJson` (uses
`ArtifactWriter.PersistFileIfChanged`, preserves old mtime on unchanged
content) followed by `<Touch Files="$(_WasmBuildBootJsonPath)" />`
(added in dotnet#125367 to keep MSBuild's I/O check on this target happy).
2. `$(_WasmBuildBootJsonPath)` — `obj/{cfg}/{tfm}/dotnet.js` — is also a
source for the StaticWebAssets compression pipeline
(`GenerateBuildCompressedStaticWebAssets` → `GZipCompress`).
3. `GZipCompress.cs` skips when `input.mtime < output.mtime` (strict
`<`). When `Touch` lands close enough in time to the `.gz` write (or any
subsequent target re-stamps dotnet.js), equal/newer mtimes send the next
build's compression task down the re-compress path.
4. Re-compression on build #2 bumps `obj/.../{0}.gz` mtime past
`bin/.../dotnet.{fp}.js.gz` (which was copied during build #1 and isn't
touched since), so `_BuildCopyStaticWebAssetsPreserveNewest` reports its
input newer than its output. `-question` fails.
This is a regression of dotnet#118637 (Aug 2025, *"Override boot config only
when the content changes"*), which fixed the exact same
`_BuildCopyStaticWebAssetsPreserveNewest` symptom in
dotnet/aspnetcore#63207 by introducing
`ArtifactWriter.PersistFileIfChanged`. PR dotnet#125367's `<Touch>` undid that
protection.
## Fix
Touch a separate `wasm-bootjson-{build,publish}.complete.stamp` file
rather than the boot JSON itself, and use the stamp as the target's
`Outputs=`. MSBuild's incrementality check on the boot-JSON target stays
correct (its declared output has a current mtime after every successful
run), while the boot JSON's mtime remains content-derived — preserving
dotnet#118637's invariant for downstream consumers.
Applied to both:
- `_WriteBuildWasmBootJsonFile` (build)
- `GeneratePublishWasmBootJson` (publish)
Both have identical shape and the same downstream consumers
(StaticWebAssets compression / Copy targets).
## What's not fixed here
- `_ConvertBuildDllsToWebcil` (line 431) uses the same `<Touch>` pattern
but on per-item-batched `@(_WasmConvertedWebcilOutputs)`. It is
*probably* exposed to the same cascade for the webcil files; not
addressed here pending a per-item analysis.
- Defense-in-depth in `dotnet/sdk`: `GZipCompress`/`BrotliCompress` `<`
mtime check could become `<=` to harden the entire StaticWebAssets
pipeline against this class of cascade. Worth a separate dotnet/sdk PR.
## Verification
- Reproduces on `dotnet/runtime` PR dotnet#129454 build
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1470806
(`browser-wasm windows Release WasmBuildTests`, workitem
`WBT-NoWebcil-MONO-ST-Wasm.Build.Tests.WasmTemplateTests`).
- The WBT theory case
`TypeScriptDefinitionsCopiedToWwwrootOnBuild(Debug|Release,
emitTypeScriptDts:True)` exercises the `dotnet build -question`
second-build check that this fix addresses.
Fixesdotnet#129280
> [!NOTE]
> This pull request was created with the assistance of GitHub Copilot.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ManickaP pushed a commit that referenced this pull request Jul 30, 2026
)
Fixesdotnet#106712.
## Summary
`GC.GetTotalMemory(false)` intermittently returns a **negative** value
under the **regions** GC (the default since .NET 7). The value
originates in `GCHeap::ApproxTotalBytesInUse`, which estimates gen0 live
bytes as `gen0_size - gen0_frag` using unsigned `size_t` arithmetic.
`gen0_frag` (free-list + free-object space) is a *per-generation* total
that spans **every** gen0 region, but `gen0_size` only summed region
spans up to the **ephemeral** region. When gen0 retains another region
(for example one pinned in place and swept rather than compacted), that
region's fragmentation stays in `gen0_frag` while its span is dropped
from `gen0_size`, so `gen0_frag > gen0_size`, the subtraction
underflows, and the public API casts the near-`2^64` `size_t` to a
negative `long`.
**In plain words:** gen0 live bytes are "space minus holes." With
**segments**, gen0 is a single contiguous block, so the holes are always
a subset of the space and the subtraction can't go negative. With
**regions**, gen0 is a linked list of blocks, and the code summed the
holes over the whole list but measured the space over only part of it -
so the holes could exceed the space and the unsigned subtraction
wrapped.
The negative is only the *visible* symptom. The same miscount also makes
`GetTotalMemory` **silently under-report** gen0 whenever the dropped
span is smaller than `gen0_frag` (positive but too low) - observed
returning ~0.4 MB where the correct value was ~16.0 MB.
## Root cause
```cpp
size_t gen0_frag = generation_free_list_space(gen0) + generation_free_obj_space(gen0);
// gen0_size summed region spans, but stopped at the ephemeral region:
// if (gen0_seg == current_eph_seg) break;
totsize = gen0_size - gen0_frag; // size_t underflow when gen0_frag > gen0_size
```
Two mechanisms, neither a GC race:
1. **Multi-region gen0 span miscount (dominant).** Any gen0 region
linked after the ephemeral one had its span dropped from `gen0_size`
while its fragmentation stayed in `gen0_frag`.
2. **Discard-branch transient (secondary and minor).** In
`a_fit_free_list_p`'s free-list discard path, `free_obj_space` is
incremented before `free_list_space` is decremented, so a lock-free
reader could briefly observe both - a transient over-count.
### Why a forced `GC.GetTotalMemory(true)` (and continued allocation)
self-heals
The reported observation that a forced `GetTotalMemory(true)` returns a
sane value and stops the negatives - and that continued allocation walks
the value back positive - follows directly from Mechanism #1. The bytes
are never wrong; only the lock-free *measurement* is.
- **`GetTotalMemory(true)` forces blocking, compacting GC(s).** Without
pinning, gen0 is fully compacted: survivors are relocated, the
swept-in-place regions linked *after* the ephemeral one are reclaimed,
and gen0's free-space counters reset. Gen0 collapses to a clean layout
where the counted span again covers all its fragmentation (`gen0_frag ≤
gen0_size`), so the next computation is correct — the bad **layout is
repaired**.
- **Continued allocation also recovers it without a GC.** As the mutator
allocates, `alloc_allocated` advances in the ephemeral region, so the
counted `gen0_size` grows; once it climbs back above `gen0_frag` the
subtraction stops underflowing. The value flip-flops as allocation and
GCs change which snapshot a read catches.
## The fix
- **`src/coreclr/gc/interface.cpp`** - walk **every** gen0 region when
computing `gen0_size` (removing the early `break` at the ephemeral
region), so the counted span matches the per-generation fragmentation
total. This mirrors how `generation_size()` in `plan_phase.cpp` walks
the whole region chain
- **defensive clamp** - compute `totsize = (gen0_size > gen0_frag) ?
(gen0_size - gen0_frag) : 0` instead of an unguarded `size_t`
subtraction. The first fix removes the reproducible underflow at its
source; the clamp guarantees the residual lock-free transient described
below can never surface as a negative from `GC.GetTotalMemory`
- (cancelled) **`src/coreclr/gc/allocation.cpp`** - reorder the
discard-branch bookkeeping (`unlink` → `free_list_space -=` →
`free_obj_space +=`) so the only transient a concurrent reader can
observe is a harmless **under-count** instead of an over-count that
could underflow. The final state is identical; this flips the
transient's direction rather than removing it. After discussion this was
not taken, as also inaccurate and misleading.
## Why this is regions-only
With segments, gen0 lives inside a single contiguous ephemeral segment;
its fragmentation is by construction a subset of the counted span, so
the subtraction can never underflow. The bug requires gen0 to span
multiple regions with one retained past the ephemeral one — only
possible under regions. Empirically, with the same source and workload:
built-in `coreclr.dll` (regions) → NEG −12,194,016 @ 97 ms; standalone
`clrgcexp.dll` (regions) → NEG −12,158,984 @ 96 ms; standalone
`clrgc.dll` (segments) → **0 negatives** over 13.5 M probes. Matches the
field report that `DOTNET_GCName=clrgc.dll` doesn't repro.
## Reproduction
Two repros, both run by swapping only `coreclr.dll` between fixed and
unfixed builds:
- **Amplifier (reliable, used by the regression test).** A console app
keeps a large, continuously-refreshed ring of **pinned** tiny objects
(forcing retained gen0 regions) while flooding gen0 with garbage and
probing `GC.GetTotalMemory` on another thread. Fails in well under a
second (~60–70 K probes, e.g. NEG −12,183,896), and fires even
single-threaded (`threads=1`) — confirming a structural miscount, not a
race.
- **The reporter's exact repros from the issue** (only change: a
wall-clock cap), which use **no pinning**:
| @kg repro (unmodified logic) | Unfixed net11 | Fixed net11 |
|---|---|---|
| **Multithreaded** (8 threads churning strings) | ❌ NEG **−2,883,184**
after 140,958 probes @ **703 ms** — "fails instantly", as reported | ✅
**9.3 M** probes / 25 s, no negative |
| **Single-threaded** (rare) | did not fire in our windows (Debug 356 K
/ 900 s, Release 5.3 M / 900 s, min ≥ 0) — matches "takes longer to
reproduce" | ✅ clean |
Takeaway: pinning is a *reliable amplifier*, **not a prerequisite** —
heavy multithreaded churn triggers frequent GCs that transiently
reshuffle the gen0 region list into the same buggy layout.
## Testing
### New regression test
`src/tests/GC/API/GC/GetTotalMemoryConcurrent.cs` (+ `.csproj`),
priority 1, process-isolated, `GCStressIncompatible`, `[Fact]
TestEntryPoint` idiom. It runs the pinned + concurrent-probe workload
and fails if any probe is negative. Pinning converts the rare transient
into a deterministic, structural repro that fires in milliseconds.
**Proven fail → pass** (swapping only `coreclr.dll` fixed↔unfixed), on
**both Debug and full Release**:
| Build | Runtime | Result |
|---|---|---|
| **Debug** | Unfixed | ❌ exit **101** — negative `-11,997,832` after
100,285 probes |
| **Debug** | Fixed | ✅ exit **100**, 3/3 runs, ~2.8–2.9 M probes each,
min ≈ +566,768 |
| **Release** | Unfixed | ❌ exit **101** — negative `-11,970,520` after
only 83,187 probes |
| **Release** | Fixed | ✅ exit **100**, 40.7–43.6 M probes, min ≈
+571,472 |
The Release run proves the fix holds on an optimized runtime; the
unfixed Release binary reproduces the negative even faster than Debug.
### Existing suite (no regressions)
`GC/API/GC/GetTotalMemory`, `TotalMemory`, `TotalMemory2`,
`GetGCMemoryInfo`, `GetTotalAllocatedBytes`,
`GetAllocatedBytesForCurrentThread` — all exit 100 against the fixed
runtime (default regions GC).
## The ".NET 10 fixed the single-threaded repro" claim — disproved
The issue notes the single-threaded (no-pin) repro was "fixed on .NET
10." Testing shows this is a **measurement artifact, not a code fix**:
the accounting site is byte-identical since regions shipped in .NET 7
(`git log -S` on the guard block returns only PR dotnet#59283 plus mechanical
`gc.cpp → interface.cpp` split commits — no .NET 8/9/10 change to the
gen0 loop or subtraction). Against installed retail runtimes:
| Repro variant | net 8.0.27 | net 9.0.16 | net 10.0.8 | net 11
(unfixed) |
|---|---|---|---|---|
| **pinned, single-threaded** | NEG −12,141,504 @ 18 ms | NEG
−11,967,528 @ 49 ms | NEG −12,103,120 @ 15 ms | NEG −12,189,472 @ 147 ms
|
| **no-pin, multithreaded** | NEG −417,696 @ 50 ms | NEG −2,083,192 @ 10
ms | NEG −741,272 @ 25 ms | *(regions repro)* |
| **no-pin, single-threaded** | 0 neg / 60 s | 0 neg / 120 s | 0 neg /
120 s | 0 neg / 60 s |
The structural underflow is single-thread-reproducible on **every**
shipping version (15–49 ms with pinning). The no-pin single-threaded
case is simply a rare transient on all versions (identical .NET 9 vs 10
behavior) — the perceived ".NET 10 fix" is timing noise, not a
behavioral change. This PR is the first actual correction of the root
cause.
## Impact & blast radius
`ApproxTotalBytesInUse` is reached only via
`GCHeap::GetTotalBytesInUse`, whose only callers are the
`System.GC.GetTotalMemory(bool)` QCall (CoreCLR) and
`RhpGetTotalBytesInUse` (NativeAOT). The one in-box managed consumer is
`RuntimeEventSource`'s **`gc-heap-size`** `PollingCounter`
(`GC.GetTotalMemory(false) / 1e6`), which surfaces the negative through
EventCounters / `dotnet-counters` / EventPipe / APM telemetry.
- **No public API surface change** — same signature and semantics, just
a corrected number. Also repairs the `forceFullCollection: true`
stabilization loop in `GetTotalMemory(bool)`, whose `diff = (newSize −
size) / size` convergence test was meaningless while `size` was
underflowed.
- **Risk is confined to accounting** — the change alters nothing about
what the GC collects, promotes, or decommits. `interface.cpp` adds a
bounded region walk (gen0 region count, single digits) plus a clamped
subtraction, both under the already-held `gc_lock`.
## Performance impact
`GetTotalMemory` is a diagnostic API (the `gc-heap-size` counter polls
it ~1×/sec), not a hot path. Local A/B (same build, only `coreclr.dll`
swapped; no allocation in the timed section; batched quantum-free mean;
workstation GC, x64):
**Release (shipping configuration — authoritative):**
| Scenario | Unfixed | Fixed | Delta |
|---|---|---|---|
| Common case (`pins=0`, single gen0 region) | ~45.4 ns | ~43.7 ns |
**≈0 ns** (identical result 626,712) |
| Fragmented (`pins=40000`, several regions) | ~48.8 ns (under-counts:
0.4 M) | ~47.0 ns (correct: 16.0 M) | **≈0 ns** (within noise) |
**Debug (checked; absolute numbers and delta both inflated by contract
checks):**
| Scenario | Unfixed | Fixed | Delta |
|---|---|---|---|
| Common case (`pins=0`) | ~535.7 ns | ~537.8 ns | +~2 ns (≈0 %) |
| Fragmented (`pins=40000`) | ~558.5 ns (under-counts: 0.4 M) | ~611.2
ns (correct: 16.0 M) | +~53 ns (+~9 %) |
The common case is free on either config (a single gen0 region means the
fix walks the same one region). The Debug fragmented +53 ns is
**Debug-accessor overhead** (contract checks on
`heap_segment_next/_mem/_allocated`, `in_range_for_segment`), not a real
cost — Release shows ≈0 in both scenarios. Cost is bounded by the
(inherently small) gen0 region count.
> [!NOTE]
> This pull request was prepared with the assistance of AI (GitHub
Copilot). The root-cause analysis, fix, and regression test were
reviewed by me before submitting.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot-Session: 975e6875-e7d4-4172-8d1f-5ed514017a4d
Copilot-Session: 2da4f5bf-503e-4a71-a1df-f73e8aedbfe2
Copilot-Session: ad1ce451-e247-42ec-accc-c4a688fcd555
ManickaP pushed a commit that referenced this pull request Jul 30, 2026
…otnet#131536)
The test intentionally expects an unhandled exception to occur. The
helix test wrapper enables crash reporting in
https://github.com/dotnet/runtime/blob/d75c1ca395b6f4e4d14925207c3d0e421f6e78e1/eng/testing/RunnerTemplate.sh#L118-L119,
but this test specifically disables `DOTNET_DbgEnableMiniDump` to
disable the only crash reporter at the time, createdump.
With the in-proc crashreporter supported on macOS and Linux, there are
now two crash reporting mechanisms, with the in-proc crash reporter
being enabled should
`DOTNET_EnableCrashReport`/`DOTNET_EnableCrashReportOnly` be set while
`DOTNET_DbgEnableMiniDump` is unset. As a result, this test
unintentionally began crash reporting after inducing unhandled exception
scenarios.
## Originally
```
Test process unhandled.dll with argument main exited
"Unhandled exception. System.Exception: Test"
" at TestUnhandledException.Program.Main(String[] args)"
Test process exited with expected error code and produced expected output
```
## InProc CrashReporter enabled
```
Test process unhandled.dll with argument main exited
"Unhandled exception. System.Exception: Test"
" at TestUnhandledException.Program.Main(String[] args)"
"*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** "
".NET Crash Report v1.0.0"
"Build: 42.42.42.42424 @Commit: c1b4860"
"ABI: arm64"
"Cmdline: corerun"
"pid: 4263"
"signal 6 (SIGABRT)"
""
"--- thread 0x164f8f (crashed) ---"
" managed exception: System.Exception (0x80131500)"
" #00 [0] TestUnhandledException.Program.Main + 0x1e (token=0x6000009)"
" #1 [1] System.Environment.CallEntryPoint + 0x1c (token=0x60004a1)"
""
"--- thread 0x164f95 ---"
" (no managed frames)"
""
"modules:"
" [0] unhandled {5818b8c6-ff2f-4925-82a6-4ed6871d1d16}"
" [1] System.Private.CoreLib {9fdb0c05-8392-43fe-8a44-1df8a41aaf06}"
" *** *** *** *** *** *** *** *** *** *** *** *** *** *** "
""
Test process exited with expected error code and produced expected output
```
This PR cleans the test output by removing DOTNET_EnableCrashReport,
thereby disabling the inproc crash reporter.
It applies the same changes for similarly crash-expecting tests
---------
Copilot-Session: 13d168eb-c2c9-410e-b5fb-be2637ac4e9a
ManickaP pushed a commit that referenced this pull request Aug 5, 2026
…otnet#130530)
This PR contains two related optimizations to generic type loading /
interface slot handling in the CoreCLR type loader.
## 1. Reuse typical instantiation DispatchMap for generic instantiations
When loading a non-typical instantiation of a generic type that
undergoes a full `MethodTableBuilder` run (the `__Canon` canonical form
and value-type instantiations such as `List<int>`), the interface
`DispatchMap` was rebuilt from scratch via `PlaceInterfaceMethods` for
every instantiation. The encoded `DispatchMap` is
instantiation-independent (it stores type IDs and slot numbers), so it
can instead be built once while constructing the type's *typical*
instantiation and reused for all of its non-typical instantiations.
- **Release**: `PlaceInterfaceMethods` is skipped for a non-typical
instantiation when the typical instantiation's `DispatchMap` can be
reused, and the typical instantiation's encoded map bytes are copied
into the new `MethodTable`'s inline `DispatchMap`.
- **Debug/Checked**: the specific instantiation's `DispatchMap` is still
built and asserted to be byte-for-byte identical to the typical
instantiation's map, guarding the instantiation-independence invariant.
This is safe because `PlaceInterfaceMethods` only produces `DispatchMap`
interface entries (it does not mutate the vtable; `PlaceMethodImpls`
still always runs), and the two consumers that read the half-built
dispatch map after `PlaceInterfaceMethods`
(`ValidateInterfaceMethodConstraints` and
`VerifyVirtualMethodsImplemented`) are already skipped for non-typical
instantiations because `fNoSanityChecks` is `TRUE` for them.
## 2. Avoid iterating interface methods to size virtual-static slot
table
`bmtInterfaceEntry::CreateSlotTable` walked every method of an interface
that has virtual static methods, counting the static+virtual ones solely
to size the `bmtInterfaceSlotImpl` array. The subsequent loop already
recomputes the exact per-method placement, so the array can simply be
over-allocated to the interface's method count, eliminating the extra
`MethodIterator` walk.
## Validation
- Release and Checked `clr.runtime` builds succeed with 0
warnings/errors.
- The Debug/Checked byte-equality assert (change #1) was exercised at
runtime on a small generics workload: the reuse+validation branch
executed 141 times, all passing the byte-equality assert, with correct
interface dispatch.
## Performance
Measured on an Rx cold-start micro-benchmark that isolates the
`System.Reactive` construct+initialize type-loading path (interleaved
A/B, 60 iterations each, release `coreclr.dll` swapped, baseline =
before both changes):
| Variant | Median workload | vs baseline |
|---|---|---|
| Baseline (neither change) | 252.15 ms | — |
| DispatchMap reuse only | 248.61 ms | −3.07 ms (−1.2%) |
| **Both changes** | **248.62 ms** | **−3.53 ms (−1.4%)** |
Standard deviation was ~1.8 ms, so the ~1.4% improvement is a clear
signal on type-loading-bound workloads. On WPF R2R startup (where type
loading is a much smaller fraction of total startup) the effect is
smaller and within run-to-run noise.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
Copilot-Session: 3bea685d-50eb-4245-b1ea-4310df00c7d3
Copilot-Session: 11ab8b48-7c38-47af-a41b-d1a9637c5f96
ManickaP pushed a commit that referenced this pull request Aug 5, 2026
…rs (dotnet#129688)
See discussion at
dotnet#121981 (comment)
# SuperPMI ASM diffs: ExtractMostSignificantBits
Base JIT: `artifacts/asmdiff/builds/59979e64/core_root/libclrjit.so` Diff JIT:
`artifacts/tests/coreclr/linux.arm64.Checked/Tests/Core_Root/libclrjit.so`
MCH: `/tmp/ExtractMostSignificantBits_final.mch` Base commit: `59979e6401a` (`origin/main`) Diff commit: `e37c3840564`
## Short summary
Diffs are based on <span style="color:#1460aa">39</span> contexts (<span
style="color:#1460aa">0</span> MinOpts, <span
style="color:#1460aa">39</span> FullOpts).
<details>
<summary>Overall (<span style="color:green">-480</span> bytes)</summary>
<div style="margin-left:1em">
|Collection|Base size (bytes)|Diff size (bytes)|PerfScore in Diffs
|---|--:|--:|--:|
|ExtractMostSignificantBits_final.mch|8,492|<span
style="color:green">-480</span>|<span
style="color:green">-28.40%</span>|
</div></details>
<details>
<summary>FullOpts (<span style="color:green">-480</span>
bytes)</summary>
<div style="margin-left:1em">
|Collection|Base size (bytes)|Diff size (bytes)|PerfScore in Diffs
|---|--:|--:|--:|
|ExtractMostSignificantBits_final.mch|8,492|<span
style="color:green">-480</span>|<span
style="color:green">-28.40%</span>|
</div></details>
## SuperPMI summary
Diffs are based on <span style="color:#1460aa">39</span> contexts (<span
style="color:#1460aa">0</span> MinOpts, <span
style="color:#1460aa">39</span> FullOpts).
<details>
<summary>Overall (<span style="color:green">-480</span> bytes)</summary>
<div style="margin-left:1em">
|Collection|Base size (bytes)|Diff size (bytes)|PerfScore in Diffs
|---|--:|--:|--:|
|ExtractMostSignificantBits_final.mch|8,492|<span
style="color:green">-480</span>|<span
style="color:green">-28.40%</span>|
</div></details>
<details>
<summary>FullOpts (<span style="color:green">-480</span>
bytes)</summary>
<div style="margin-left:1em">
|Collection|Base size (bytes)|Diff size (bytes)|PerfScore in Diffs
|---|--:|--:|--:|
|ExtractMostSignificantBits_final.mch|8,492|<span
style="color:green">-480</span>|<span
style="color:green">-28.40%</span>|
</div></details>
<details>
<summary>Example diffs</summary>
<div style="margin-left:1em">
<details>
<summary>ExtractMostSignificantBits_final.mch</summary>
<div style="margin-left:1em">
<details>
<summary><span style="color:green">-44</span> (<span
style="color:green">-52.38%</span>) : 17.dasm -
TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -7,10 +7,9 @@
; No matching PGO data
; Final local variable assignments
;
-; V00 arg0 [V00,T02] ( 3, 3 ) simd16 -> d0 single-def <System.Runtime.Intrinsics.Vector128`1[byte]>
+; V00 arg0 [V00,T01] ( 3, 3 ) simd16 -> d0 single-def <System.Runtime.Intrinsics.Vector128`1[byte]>
; V01 arg1 [V01,T00] ( 3, 3 ) ubyte -> x0 single-def
;# V02 OutArgs [V02 ] ( 1, 1 ) struct ( 0) [sp+0x00] do-not-enreg[XS] addr-exposed "OutgoingArgSpace" <Empty>
-; V03 rat0 [V03,T01] ( 3, 6 ) simd16 -> d16 "ReplaceWithLclVar is creating a new local variable"
;
; Lcl frame size = 0
@@ -18,33 +17,20 @@ G_M10966_IG01: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref,
stp fp, lr, [sp, #-0x10]!
mov fp, sp
;; size=8 bbWeight=1 PerfScore 1.50
-G_M10966_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref, isz
+G_M10966_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
uxtb w0, w0
dup v16.16b, w0
cmhs v16.16b, v0.16b, v16.16b
- movi v17.16b, #0x80
- and v16.16b, v16.16b, v17.16b
- ldr q17, [@rwd00]
- ushl v16.16b, v16.16b, v17.16b
- uxtl2 v17.8h, v16.16b
- shl v17.8h, v17.8h, #8
- uaddw v16.8h, v17.8h, v16.8b
- addv h16, v16.8h
- umov w0, v16.h[0]
- movi v16.8b, #0
- ins v16.s[0], w0
- cnt v16.8b, v16.8b
- addv b16, v16.8b
- umov w0, v16.s[0]
- ;; size=68 bbWeight=1 PerfScore 20.00
+ ushr v16.16b, v16.16b, #7
+ addv b16, v16.16b
+ umov w0, v16.b[0]
+ ;; size=24 bbWeight=1 PerfScore 7.50
G_M10966_IG03: ; bbWeight=1, epilog, nogc, extend
ldp fp, lr, [sp], #0x10
ret lr
;; size=8 bbWeight=1 PerfScore 2.00
-RWD00 dq	00FFFEFDFCFBFAF9h, 00FFFEFDFCFBFAF9h
-
-; Total bytes of code 84, prolog size 8, PerfScore 23.50, instruction count 21, allocated bytes for code 84 (MethodHash=3eafd529) for method TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
+; Total bytes of code 40, prolog size 8, PerfScore 11.00, instruction count 10, allocated bytes for code 40 (MethodHash=3eafd529) for method TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
; ============================================================
Unwind Info:
@@ -55,7 +41,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 21 (0x00015) Actual length = 84 (0x000054)
+ Function Length : 10 (0x0000a) Actual length = 40 (0x000028)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
<details>
<summary><span style="color:green">-32</span> (<span
style="color:green">-47.06%</span>) : 12.dasm -
TestExtractMostSignificantBits.Program:CountLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):int
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -17,29 +17,19 @@ G_M46948_IG01: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref,
stp fp, lr, [sp, #-0x10]!
mov fp, sp
;; size=8 bbWeight=1 PerfScore 1.50
-G_M46948_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref, isz
+G_M46948_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
dup v16.4s, w0
cmgt v16.4s, v16.4s, v0.4s
- movi v17.4s, #0x80, LSL dotnet#24
- and v16.4s, v16.4s, v17.4s
- ldr q17, [@rwd00]
- ushl v16.4s, v16.4s, v17.4s
+ ushr v16.4s, v16.4s, dotnet#31
addv s16, v16.4s
- smov x0, v16.s[0]
- movi v16.8b, #0
- ins v16.s[0], w0
- cnt v16.8b, v16.8b
- addv b16, v16.8b
umov w0, v16.s[0]
- ;; size=52 bbWeight=1 PerfScore 15.50
+ ;; size=20 bbWeight=1 PerfScore 7.00
G_M46948_IG03: ; bbWeight=1, epilog, nogc, extend
ldp fp, lr, [sp], #0x10
ret lr
;; size=8 bbWeight=1 PerfScore 2.00
-RWD00 dq	FFFFFFE2FFFFFFE1h, FFFFFFE4FFFFFFE3h
-
-; Total bytes of code 68, prolog size 8, PerfScore 19.00, instruction count 17, allocated bytes for code 68 (MethodHash=d8b1489b) for method TestExtractMostSignificantBits.Program:CountLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):int (FullOpts)
+; Total bytes of code 36, prolog size 8, PerfScore 10.50, instruction count 9, allocated bytes for code 36 (MethodHash=d8b1489b) for method TestExtractMostSignificantBits.Program:CountLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):int (FullOpts)
; ============================================================
Unwind Info:
@@ -50,7 +40,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 17 (0x00011) Actual length = 68 (0x000044)
+ Function Length : 9 (0x00009) Actual length = 36 (0x000024)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
<details>
<summary><span style="color:green">-32</span> (<span
style="color:green">-47.06%</span>) : 27.dasm -
TestExtractMostSignificantBits.Program:CountLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):int
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -18,29 +18,19 @@ G_M44223_IG01: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref,
stp fp, lr, [sp, #-0x10]!
mov fp, sp
;; size=8 bbWeight=1 PerfScore 1.50
-G_M44223_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref, isz
+G_M44223_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref
dup v16.2s, w0
cmgt v16.2s, v16.2s, v0.2s
- movi v17.2s, #0x80, LSL dotnet#24
- and v16.2s, v16.2s, v17.2s
- ldr d17, [@rwd00]
- ushl v16.2s, v16.2s, v17.2s
+ ushr v16.2s, v16.2s, dotnet#31
addp v16.2s, v16.2s, v16.2s
- smov x0, v16.s[0]
- movi v16.8b, #0
- ins v16.s[0], w0
- cnt v16.8b, v16.8b
- addv b16, v16.8b
umov w0, v16.s[0]
- ;; size=52 bbWeight=1 PerfScore 15.50
+ ;; size=20 bbWeight=1 PerfScore 7.00
G_M44223_IG03: ; bbWeight=1, epilog, nogc, extend
ldp fp, lr, [sp], #0x10
ret lr
;; size=8 bbWeight=1 PerfScore 2.00
-RWD00 dq	FFFFFFE2FFFFFFE1h
-
-; Total bytes of code 68, prolog size 8, PerfScore 19.00, instruction count 17, allocated bytes for code 68 (MethodHash=6ccd5340) for method TestExtractMostSignificantBits.Program:CountLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):int (FullOpts)
+; Total bytes of code 36, prolog size 8, PerfScore 10.50, instruction count 9, allocated bytes for code 36 (MethodHash=6ccd5340) for method TestExtractMostSignificantBits.Program:CountLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):int (FullOpts)
; ============================================================
Unwind Info:
@@ -51,7 +41,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 17 (0x00011) Actual length = 68 (0x000044)
+ Function Length : 9 (0x00009) Actual length = 36 (0x000024)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
<details>
<summary><span style="color:green">-8</span> (<span
style="color:green">-13.33%</span>) : 33.dasm -
TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):int
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -21,23 +21,21 @@ G_M59363_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref,
uxtb w0, w0
dup v16.8b, w0
cmhs v16.8b, v0.8b, v16.8b
- movi v17.8b, #0x80
- and v16.8b, v16.8b, v17.8b
ldr d17, [@rwd00]
- ushl v16.8b, v16.8b, v17.8b
- addv b16, v16.8b
+ movi v18.8b, #0x21
+ bsl v16.8b, v17.8b, v18.8b
+ uminv b16, v16.8b
umov w0, v16.b[0]
- rbit w0, w0
- clz w0, w0
- ;; size=44 bbWeight=1 PerfScore 12.00
+ sub w0, w0, #1
+ ;; size=36 bbWeight=1 PerfScore 11.00
G_M59363_IG03: ; bbWeight=1, epilog, nogc, extend
ldp fp, lr, [sp], #0x10
ret lr
;; size=8 bbWeight=1 PerfScore 2.00
-RWD00 dq	00FFFEFDFCFBFAF9h
+RWD00 dq	0807060504030201h
-; Total bytes of code 60, prolog size 8, PerfScore 15.50, instruction count 15, allocated bytes for code 60 (MethodHash=312b181c) for method TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):int (FullOpts)
+; Total bytes of code 52, prolog size 8, PerfScore 14.50, instruction count 13, allocated bytes for code 52 (MethodHash=312b181c) for method TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):int (FullOpts)
; ============================================================
Unwind Info:
@@ -48,7 +46,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 15 (0x0000f) Actual length = 60 (0x00003c)
+ Function Length : 13 (0x0000d) Actual length = 52 (0x000034)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
<details>
<summary><span style="color:green">-8</span> (<span
style="color:green">-13.33%</span>) : 23.dasm -
TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):int
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -21,23 +21,21 @@ G_M61416_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref,
uxth w0, w0
dup v16.4h, w0
cmhs v16.4h, v0.4h, v16.4h
- movi v17.4h, #0x80, LSL #8
- and v16.4h, v16.4h, v17.4h
ldr d17, [@rwd00]
- ushl v16.4h, v16.4h, v17.4h
- addv h16, v16.4h
+ movi v18.4h, #0x21
+ bsl v16.4h, v17.4h, v18.4h
+ uminv h16, v16.4h
umov w0, v16.h[0]
- rbit w0, w0
- clz w0, w0
- ;; size=44 bbWeight=1 PerfScore 12.00
+ sub w0, w0, #1
+ ;; size=36 bbWeight=1 PerfScore 11.00
G_M61416_IG03: ; bbWeight=1, epilog, nogc, extend
ldp fp, lr, [sp], #0x10
ret lr
;; size=8 bbWeight=1 PerfScore 2.00
-RWD00 dq	FFF4FFF3FFF2FFF1h
+RWD00 dq	0004000300020001h
-; Total bytes of code 60, prolog size 8, PerfScore 15.50, instruction count 15, allocated bytes for code 60 (MethodHash=ba031017) for method TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):int (FullOpts)
+; Total bytes of code 52, prolog size 8, PerfScore 14.50, instruction count 13, allocated bytes for code 52 (MethodHash=ba031017) for method TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):int (FullOpts)
; ============================================================
Unwind Info:
@@ -48,7 +46,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 15 (0x0000f) Actual length = 60 (0x00003c)
+ Function Length : 13 (0x0000d) Actual length = 52 (0x000034)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
<details>
<summary><span style="color:green">-8</span> (<span
style="color:green">-13.33%</span>) : 8.dasm -
TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):int
(FullOpts)</summary>
<div style="margin-left:1em">
```diff
@@ -21,23 +21,21 @@ G_M44819_IG02: ; bbWeight=1, gcrefRegs=0000 {}, byrefRegs=0000 {}, byref,
uxth w0, w0
dup v16.8h, w0
cmhs v16.8h, v0.8h, v16.8h
- movi v17.8h, #0x80, LSL #8
- and v16.8h, v16.8h, v17.8h
ldr q17, [@rwd00]
- ushl v16.8h, v16.8h, v17.8h
- addv h16, v16.8h
+ movi v18.8h, #0x21
+ bsl v16.8h, v17.8h, v18.8h
+ uminv h16, v16.8h
umov w0, v16.h[0]
- rbit w0, w0
- clz w0, w0
- ;; size=44 bbWeight=1 PerfScore 12.00
+ sub w0, w0, #1
+ ;; size=36 bbWeight=1 PerfScore 11.00
G_M44819_IG03: ; bbWeight=1, epilog, nogc, extend
ldp fp, lr, [sp], #0x10
ret lr
;; size=8 bbWeight=1 PerfScore 2.00
-RWD00 dq	FFF4FFF3FFF2FFF1h, FFF8FFF7FFF6FFF5h
+RWD00 dq	0004000300020001h, 0008000700060005h
-; Total bytes of code 60, prolog size 8, PerfScore 15.50, instruction count 15, allocated bytes for code 60 (MethodHash=016950ec) for method TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):int (FullOpts)
+; Total bytes of code 52, prolog size 8, PerfScore 14.50, instruction count 13, allocated bytes for code 52 (MethodHash=016950ec) for method TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):int (FullOpts)
; ============================================================
Unwind Info:
@@ -48,7 +46,7 @@ Unwind Info:
E bit : 0
X bit : 0
Vers : 0
- Function Length : 15 (0x0000f) Actual length = 60 (0x00003c)
+ Function Length : 13 (0x0000d) Actual length = 52 (0x000034)
---- Epilog scopes ----
---- Scope 0
Epilog Start Offset : 3523193630 (0xd1ffab1e) Actual offset = 3523193630 (0xd1ffab1e) Offset from main function begin = 3523193630 (0xd1ffab1e)
```
</div></details>
</div></details>
</div></details>
<details>
<summary>Details</summary>
<div style="margin-left:1em">
#### Size improvements/regressions per collection
|Collection|Contexts with diffs|Improvements|Regressions|Same
size|Improvements (bytes)|Regressions (bytes)|
|---|--:|--:|--:|--:|--:|--:|
|ExtractMostSignificantBits_final.mch|24|<span
style="color:green">24</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span style="color:green">-480</span>|<span
style="color:red">+0</span>|
---
#### PerfScore improvements/regressions per collection
|Collection|Contexts with diffs|Improvements|Regressions|Same
PerfScore|Improvements (PerfScore)|Regressions (PerfScore)|PerfScore
Overall in FullOpts|
|---|--:|--:|--:|--:|--:|--:|--:|
|ExtractMostSignificantBits_final.mch|24|<span
style="color:green">24</span>|<span style="color:red">0</span>|<span
style="color:blue">0</span>|<span
style="color:green">-28.40%</span>|0.00%|<span
style="color:green">-18.5844%</span>|
---
#### Context information
|Collection|Diffed contexts|MinOpts|FullOpts|Missed, base|Missed, diff|
|---|--:|--:|--:|--:|--:|
|ExtractMostSignificantBits_final.mch|39|0|39|0 (0.00%)|0 (0.00%)|
---
#### jit-analyze output
<details>
<summary>ExtractMostSignificantBits_final.mch</summary>
<div style="margin-left:1em">
```
Summary of Code Size diffs:
(Lower is better)
Total bytes of base: 8492 (overridden on cmd)
Total bytes of diff: 8012 (overridden on cmd)
Total bytes of delta: -480 (-5.65 % of base)
diff is an improvement.
relative diff is an improvement.
```
<details>
<summary>Detail diffs</summary>
```
Top file improvements (bytes):
-44 : 17.dasm (-52.38 % of base)
-32 : 22.dasm (-44.44 % of base)
-32 : 7.dasm (-44.44 % of base)
-32 : 32.dasm (-44.44 % of base)
-32 : 27.dasm (-47.06 % of base)
-32 : 12.dasm (-47.06 % of base)
-28 : 16.dasm (-38.89 % of base)
-28 : 15.dasm (-38.89 % of base)
-20 : 18.dasm (-27.78 % of base)
-16 : 30.dasm (-26.67 % of base)
-16 : 6.dasm (-26.67 % of base)
-16 : 5.dasm (-26.67 % of base)
-16 : 10.dasm (-28.57 % of base)
-16 : 26.dasm (-28.57 % of base)
-16 : 25.dasm (-28.57 % of base)
-16 : 21.dasm (-26.67 % of base)
-16 : 11.dasm (-28.57 % of base)
-16 : 31.dasm (-26.67 % of base)
-16 : 20.dasm (-26.67 % of base)
-8 : 33.dasm (-13.33 % of base)
24 total files with Code Size differences (24 improved, 0 regressed), 0 unchanged.
Top method improvements (bytes):
-44 (-52.38 % of base) : 17.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
-32 (-44.44 % of base) : 32.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):int (FullOpts)
-32 (-44.44 % of base) : 7.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):int (FullOpts)
-32 (-44.44 % of base) : 22.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):int (FullOpts)
-32 (-47.06 % of base) : 12.dasm - TestExtractMostSignificantBits.Program:CountLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):int (FullOpts)
-32 (-47.06 % of base) : 27.dasm - TestExtractMostSignificantBits.Program:CountLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):int (FullOpts)
-28 (-38.89 % of base) : 15.dasm - TestExtractMostSignificantBits.Program:AnyGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):bool (FullOpts)
-28 (-38.89 % of base) : 16.dasm - TestExtractMostSignificantBits.Program:NoneGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):bool (FullOpts)
-20 (-27.78 % of base) : 18.dasm - TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
-16 (-26.67 % of base) : 30.dasm - TestExtractMostSignificantBits.Program:AnyGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):bool (FullOpts)
-16 (-28.57 % of base) : 10.dasm - TestExtractMostSignificantBits.Program:AnyLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 25.dasm - TestExtractMostSignificantBits.Program:AnyLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):bool (FullOpts)
-16 (-26.67 % of base) : 5.dasm - TestExtractMostSignificantBits.Program:AnyLessThanUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 20.dasm - TestExtractMostSignificantBits.Program:AnyLessThanUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 31.dasm - TestExtractMostSignificantBits.Program:NoneGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):bool (FullOpts)
-16 (-28.57 % of base) : 11.dasm - TestExtractMostSignificantBits.Program:NoneLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 26.dasm - TestExtractMostSignificantBits.Program:NoneLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):bool (FullOpts)
-16 (-26.67 % of base) : 6.dasm - TestExtractMostSignificantBits.Program:NoneLessThanUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 21.dasm - TestExtractMostSignificantBits.Program:NoneLessThanUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):bool (FullOpts)
-8 (-13.33 % of base) : 33.dasm - TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):int (FullOpts)
Top method improvements (percentages):
-44 (-52.38 % of base) : 17.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
-32 (-47.06 % of base) : 12.dasm - TestExtractMostSignificantBits.Program:CountLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):int (FullOpts)
-32 (-47.06 % of base) : 27.dasm - TestExtractMostSignificantBits.Program:CountLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):int (FullOpts)
-32 (-44.44 % of base) : 32.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):int (FullOpts)
-32 (-44.44 % of base) : 7.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):int (FullOpts)
-32 (-44.44 % of base) : 22.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):int (FullOpts)
-28 (-38.89 % of base) : 15.dasm - TestExtractMostSignificantBits.Program:AnyGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):bool (FullOpts)
-28 (-38.89 % of base) : 16.dasm - TestExtractMostSignificantBits.Program:NoneGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):bool (FullOpts)
-16 (-28.57 % of base) : 10.dasm - TestExtractMostSignificantBits.Program:AnyLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 25.dasm - TestExtractMostSignificantBits.Program:AnyLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 11.dasm - TestExtractMostSignificantBits.Program:NoneLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 26.dasm - TestExtractMostSignificantBits.Program:NoneLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):bool (FullOpts)
-20 (-27.78 % of base) : 18.dasm - TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
-16 (-26.67 % of base) : 30.dasm - TestExtractMostSignificantBits.Program:AnyGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):bool (FullOpts)
-16 (-26.67 % of base) : 5.dasm - TestExtractMostSignificantBits.Program:AnyLessThanUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 20.dasm - TestExtractMostSignificantBits.Program:AnyLessThanUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 31.dasm - TestExtractMostSignificantBits.Program:NoneGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):bool (FullOpts)
-16 (-26.67 % of base) : 6.dasm - TestExtractMostSignificantBits.Program:NoneLessThanUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 21.dasm - TestExtractMostSignificantBits.Program:NoneLessThanUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):bool (FullOpts)
-8 (-14.29 % of base) : 13.dasm - TestExtractMostSignificantBits.Program:IndexOfFirstLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):int (FullOpts)
24 total methods with Code Size differences (24 improved, 0 regressed).
```
</details>
--------------------------------------------------------------------------------
</div></details>
</div></details>
## Jit-analyze summary
```
Summary of Code Size diffs:
(Lower is better)
Total bytes of base: 8492 (overridden on cmd)
Total bytes of diff: 8012 (overridden on cmd)
Total bytes of delta: -480 (-5.65 % of base)
diff is an improvement.
relative diff is an improvement.
```
<details>
<summary>Detail diffs</summary>
```
Top file improvements (bytes):
-44 : 17.dasm (-52.38 % of base)
-32 : 22.dasm (-44.44 % of base)
-32 : 7.dasm (-44.44 % of base)
-32 : 32.dasm (-44.44 % of base)
-32 : 27.dasm (-47.06 % of base)
-32 : 12.dasm (-47.06 % of base)
-28 : 16.dasm (-38.89 % of base)
-28 : 15.dasm (-38.89 % of base)
-20 : 18.dasm (-27.78 % of base)
-16 : 30.dasm (-26.67 % of base)
-16 : 6.dasm (-26.67 % of base)
-16 : 5.dasm (-26.67 % of base)
-16 : 10.dasm (-28.57 % of base)
-16 : 26.dasm (-28.57 % of base)
-16 : 25.dasm (-28.57 % of base)
-16 : 21.dasm (-26.67 % of base)
-16 : 11.dasm (-28.57 % of base)
-16 : 31.dasm (-26.67 % of base)
-16 : 20.dasm (-26.67 % of base)
-8 : 33.dasm (-13.33 % of base)
24 total files with Code Size differences (24 improved, 0 regressed), 0 unchanged.
Top method improvements (bytes):
-44 (-52.38 % of base) : 17.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
-32 (-44.44 % of base) : 32.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):int (FullOpts)
-32 (-44.44 % of base) : 7.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):int (FullOpts)
-32 (-44.44 % of base) : 22.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):int (FullOpts)
-32 (-47.06 % of base) : 12.dasm - TestExtractMostSignificantBits.Program:CountLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):int (FullOpts)
-32 (-47.06 % of base) : 27.dasm - TestExtractMostSignificantBits.Program:CountLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):int (FullOpts)
-28 (-38.89 % of base) : 15.dasm - TestExtractMostSignificantBits.Program:AnyGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):bool (FullOpts)
-28 (-38.89 % of base) : 16.dasm - TestExtractMostSignificantBits.Program:NoneGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):bool (FullOpts)
-20 (-27.78 % of base) : 18.dasm - TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
-16 (-26.67 % of base) : 30.dasm - TestExtractMostSignificantBits.Program:AnyGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):bool (FullOpts)
-16 (-28.57 % of base) : 10.dasm - TestExtractMostSignificantBits.Program:AnyLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 25.dasm - TestExtractMostSignificantBits.Program:AnyLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):bool (FullOpts)
-16 (-26.67 % of base) : 5.dasm - TestExtractMostSignificantBits.Program:AnyLessThanUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 20.dasm - TestExtractMostSignificantBits.Program:AnyLessThanUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 31.dasm - TestExtractMostSignificantBits.Program:NoneGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):bool (FullOpts)
-16 (-28.57 % of base) : 11.dasm - TestExtractMostSignificantBits.Program:NoneLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 26.dasm - TestExtractMostSignificantBits.Program:NoneLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):bool (FullOpts)
-16 (-26.67 % of base) : 6.dasm - TestExtractMostSignificantBits.Program:NoneLessThanUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 21.dasm - TestExtractMostSignificantBits.Program:NoneLessThanUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):bool (FullOpts)
-8 (-13.33 % of base) : 33.dasm - TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):int (FullOpts)
Top method improvements (percentages):
-44 (-52.38 % of base) : 17.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
-32 (-47.06 % of base) : 12.dasm - TestExtractMostSignificantBits.Program:CountLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):int (FullOpts)
-32 (-47.06 % of base) : 27.dasm - TestExtractMostSignificantBits.Program:CountLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):int (FullOpts)
-32 (-44.44 % of base) : 32.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):int (FullOpts)
-32 (-44.44 % of base) : 7.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):int (FullOpts)
-32 (-44.44 % of base) : 22.dasm - TestExtractMostSignificantBits.Program:CountGreaterThanOrEqualUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):int (FullOpts)
-28 (-38.89 % of base) : 15.dasm - TestExtractMostSignificantBits.Program:AnyGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):bool (FullOpts)
-28 (-38.89 % of base) : 16.dasm - TestExtractMostSignificantBits.Program:NoneGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):bool (FullOpts)
-16 (-28.57 % of base) : 10.dasm - TestExtractMostSignificantBits.Program:AnyLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 25.dasm - TestExtractMostSignificantBits.Program:AnyLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 11.dasm - TestExtractMostSignificantBits.Program:NoneLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):bool (FullOpts)
-16 (-28.57 % of base) : 26.dasm - TestExtractMostSignificantBits.Program:NoneLessThanInt3264(System.Runtime.Intrinsics.Vector64`1[int],int):bool (FullOpts)
-20 (-27.78 % of base) : 18.dasm - TestExtractMostSignificantBits.Program:IndexOfFirstGreaterThanOrEqualByte(System.Runtime.Intrinsics.Vector128`1[byte],byte):int (FullOpts)
-16 (-26.67 % of base) : 30.dasm - TestExtractMostSignificantBits.Program:AnyGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):bool (FullOpts)
-16 (-26.67 % of base) : 5.dasm - TestExtractMostSignificantBits.Program:AnyLessThanUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 20.dasm - TestExtractMostSignificantBits.Program:AnyLessThanUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 31.dasm - TestExtractMostSignificantBits.Program:NoneGreaterThanOrEqualByte64(System.Runtime.Intrinsics.Vector64`1[byte],byte):bool (FullOpts)
-16 (-26.67 % of base) : 6.dasm - TestExtractMostSignificantBits.Program:NoneLessThanUInt16(System.Runtime.Intrinsics.Vector128`1[ushort],ushort):bool (FullOpts)
-16 (-26.67 % of base) : 21.dasm - TestExtractMostSignificantBits.Program:NoneLessThanUInt1664(System.Runtime.Intrinsics.Vector64`1[ushort],ushort):bool (FullOpts)
-8 (-14.29 % of base) : 13.dasm - TestExtractMostSignificantBits.Program:IndexOfFirstLessThanInt32(System.Runtime.Intrinsics.Vector128`1[int],int):int (FullOpts)
24 total methods with Code Size differences (24 improved, 0 regressed).
```
</details>
--------------------------------------------------------------------------------
## Generated artifacts
- SuperPMI log: `artifacts/spmi/superpmi.27.log`
- Short summary: `artifacts/spmi/diff_short_summary.11.md`
- Full summary: `artifacts/spmi/diff_summary.11.md`
- Jit-analyze summary:
`artifacts/spmi/asm.ExtractMostSignificantBits_final/summary.md`
- Base asm: `artifacts/spmi/asm.ExtractMostSignificantBits_final/base/`
- Diff asm: `artifacts/spmi/asm.ExtractMostSignificantBits_final/diff/`
---------
Co-authored-by: Egor Bogatov <egorbo@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ManickaP@ThadHouse@nibanks@rzikm