[cdac] add v2 ExecutionManager contract for NibbleMap change - #1
[cdac] add v2 ExecutionManager contract for NibbleMap change#1max-charlamb wants to merge 7 commits into
Conversation
elinor-fung
left a comment
There was a problem hiding this comment.
Were you also able to test out the E2E combined with your runtime nibble map change? Well, the part of the E2E that we have working - for JIT-ed methods, the method names should display correctly for something like !clrstack (should go through the ExecutionManager and the nibble map in order to get the method corresponding to the IPs).
|
|
||
| namespace Microsoft.Diagnostics.DataContractReader.ExecutionManagerHelpers; | ||
|
|
||
| // CoreCLR nibblemap with O(1) lookup time. |
There was a problem hiding this comment.
Update docs/design/datacontracts/ExecutionManager.md to add version 2 with information about this nibble map?
There was a problem hiding this comment.
Added some docs and an example. I'm not sure the best way to add docs for the second version. I added a section below explaining the differences and the new algorithm.
Yes, I used WinDbg and debugged that with VS to verify that |
* 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
…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
…more APIs) (#1…" (dotnet#120138) This reverts commit 1b4eff2. Fixes dotnet#120137
…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>
…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.
…otnet#124642) ## Summary Fixes dotnet#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
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 dotnet#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>
- Fix README test filter syntax: use FullyQualifiedName~BasicAlloc (#1) - Remove goto statements from GCInfoDecoder.EnumerateLiveSlots: extract ReportUntrackedAndSucceed local function (#2) - Move CheckForSkippedFrames from Next() to UpdateState (#6) - Add XUnitConsoleRunner package reference for Helix payload (#9) - Support TypeSpec (tag=2) in DecodeTypeDefOrRefOrSpec matching native CorSigUncompressToken behavior (#10) - Fix IsAppleArm64ABI: set to false until Apple platform detection is available (filed dotnet#127282) (#11) - Fix Unix x64 float register stride: use FloatRegisterSize instead of hardcoded 8 (#12) - Replace FrameIterator.OffsetFromGCRefMapPos with CallingConventionInfo version that handles x86 reversed register layout (dotnet#13) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix README test filter syntax: use FullyQualifiedName~BasicAlloc (#1) - Remove goto statements from GCInfoDecoder.EnumerateLiveSlots: extract ReportUntrackedAndSucceed local function (#2) - Move CheckForSkippedFrames from Next() to UpdateState (#6) - Add XUnitConsoleRunner package reference for Helix payload (#9) - Support TypeSpec (tag=2) in DecodeTypeDefOrRefOrSpec matching native CorSigUncompressToken behavior (#10) - Fix IsAppleArm64ABI: set to false until Apple platform detection is available (filed dotnet#127282) (#11) - Fix Unix x64 float register stride: use FloatRegisterSize instead of hardcoded 8 (#12) - Replace FrameIterator.OffsetFromGCRefMapPos with CallingConventionInfo version that handles x86 reversed register layout (dotnet#13) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix README test filter syntax: use FullyQualifiedName~BasicAlloc (#1) - Remove goto statements from GCInfoDecoder.EnumerateLiveSlots: extract ReportUntrackedAndSucceed local function (#2) - Move CheckForSkippedFrames from Next() to UpdateState (#6) - Add XUnitConsoleRunner package reference for Helix payload (#9) - Support TypeSpec (tag=2) in DecodeTypeDefOrRefOrSpec matching native CorSigUncompressToken behavior (#10) - Fix IsAppleArm64ABI: set to false until Apple platform detection is available (filed dotnet#127282) (#11) - Fix Unix x64 float register stride: use FloatRegisterSize instead of hardcoded 8 (#12) - Replace FrameIterator.OffsetFromGCRefMapPos with CallingConventionInfo version that handles x86 reversed register layout (dotnet#13) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix README test filter syntax: use FullyQualifiedName~BasicAlloc (#1) - Remove goto statements from GCInfoDecoder.EnumerateLiveSlots: extract ReportUntrackedAndSucceed local function (#2) - Move CheckForSkippedFrames from Next() to UpdateState (#6) - Add XUnitConsoleRunner package reference for Helix payload (#9) - Support TypeSpec (tag=2) in DecodeTypeDefOrRefOrSpec matching native CorSigUncompressToken behavior (#10) - Fix IsAppleArm64ABI: set to false until Apple platform detection is available (filed dotnet#127282) (#11) - Fix Unix x64 float register stride: use FloatRegisterSize instead of hardcoded 8 (#12) - Replace FrameIterator.OffsetFromGCRefMapPos with CallingConventionInfo version that handles x86 reversed register layout (dotnet#13) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix README test filter syntax: use FullyQualifiedName~BasicAlloc (#1) - Remove goto statements from GCInfoDecoder.EnumerateLiveSlots: extract ReportUntrackedAndSucceed local function (#2) - Move CheckForSkippedFrames from Next() to UpdateState (#6) - Add XUnitConsoleRunner package reference for Helix payload (#9) - Support TypeSpec (tag=2) in DecodeTypeDefOrRefOrSpec matching native CorSigUncompressToken behavior (#10) - Fix IsAppleArm64ABI: set to false until Apple platform detection is available (filed dotnet#127282) (#11) - Fix Unix x64 float register stride: use FloatRegisterSize instead of hardcoded 8 (#12) - Replace FrameIterator.OffsetFromGCRefMapPos with CallingConventionInfo version that handles x86 reversed register layout (dotnet#13) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…128163) > [!NOTE] > This PR was authored with assistance from GitHub Copilot. Fixes dotnet#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>
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>
Three issues prevented x86 stress from passing in CI (build 1473187): 1. Leftover Console.WriteLine debug output in GCArgTable.cs flooded the Helix log with thousands of "CallArgCount/CallPndTabCnt/lastSkip/stkOffs" lines and made test triage impossible. Removed all four diagnostic writes plus their now-dead locals (stkOffs/lowBit, lastSkip+param, callPndTabSize, callPndTab read-without-use). 2. CalculatePushedArgSizeAt threw "Unsupported gc transition type" (InvalidOperationException, HRESULT 0x80131509) whenever an ESP-frame walk hit a CalleeSavedRegister transition (emitted by the partial- interrupt no-EBP decoder, case 7 / 0x04). Native scanArgRegTable treats this tag as informational (no effect on outgoing-arg depth); the cDAC switch was missing the case so every ESP-frame stack with a callee-saved-reg tag aborted GetStackReferences with hr=0x80131509. This was the source of 18-70 [FAIL] entries per debuggee in CI. 3. AddressFromGCRefMapPos used the same forward-from-FirstGCRefMapSlot formula on every architecture, but x86's TransitionBlock lays out its two argument registers (EDX/ECX) backward via ENUM_ARGUMENT_REGISTERS_BACKWARD. Native OffsetFromGCRefMapPos (frames.cpp) reverses pos 0/1 within the arg-regs area on x86. Without this fix, ExternalMethodFrame GCRefMap-driven scans reported the wrong arg-reg slot for the first two positions. Stack-arg positions (pos >= 2) remain forward, matching native. Local PInvoke debuggee under DOTNET_CdacStress=0x001: Before fix #1+#2: 70 fail / 64926 matched / 0 mismatched (every [FAIL] was an InvalidOperationException, not a real mismatch). After #1+#2: 2 fail / 66250 matched / 2 mismatched. After all three: 2 fail (remaining is a separate x86 GCRefMap decode bug in pos >= 2 stack args, tracked as follow-up). 5 of 9 debuggees now report 0 failures and 0 mismatches.
Three issues prevented x86 stress from passing in CI (build 1473187): 1. Leftover Console.WriteLine debug output in GCArgTable.cs flooded the Helix log with thousands of "CallArgCount/CallPndTabCnt/lastSkip/stkOffs" lines and made test triage impossible. Removed all four diagnostic writes plus their now-dead locals (stkOffs/lowBit, lastSkip+param, callPndTabSize, callPndTab read-without-use). 2. CalculatePushedArgSizeAt threw "Unsupported gc transition type" (InvalidOperationException, HRESULT 0x80131509) whenever an ESP-frame walk hit a CalleeSavedRegister transition (emitted by the partial- interrupt no-EBP decoder, case 7 / 0x04). Native scanArgRegTable treats this tag as informational (no effect on outgoing-arg depth); the cDAC switch was missing the case so every ESP-frame stack with a callee-saved-reg tag aborted GetStackReferences with hr=0x80131509. This was the source of 18-70 [FAIL] entries per debuggee in CI. 3. AddressFromGCRefMapPos used the same forward-from-FirstGCRefMapSlot formula on every architecture, but x86's TransitionBlock lays out its two argument registers (EDX/ECX) backward via ENUM_ARGUMENT_REGISTERS_BACKWARD. Native OffsetFromGCRefMapPos (frames.cpp) reverses pos 0/1 within the arg-regs area on x86. Without this fix, ExternalMethodFrame GCRefMap-driven scans reported the wrong arg-reg slot for the first two positions. Stack-arg positions (pos >= 2) remain forward, matching native. Local PInvoke debuggee under DOTNET_CdacStress=0x001: Before fix #1+#2: 70 fail / 64926 matched / 0 mismatched (every [FAIL] was an InvalidOperationException, not a real mismatch). After #1+#2: 2 fail / 66250 matched / 2 mismatched. After all three: 2 fail (remaining is a separate x86 GCRefMap decode bug in pos >= 2 stack args, tracked as follow-up). 5 of 9 debuggees now report 0 failures and 0 mismatches.
Three issues prevented x86 stress from passing in CI (build 1473187): 1. Leftover Console.WriteLine debug output in GCArgTable.cs flooded the Helix log with thousands of "CallArgCount/CallPndTabCnt/lastSkip/stkOffs" lines and made test triage impossible. Removed all four diagnostic writes plus their now-dead locals (stkOffs/lowBit, lastSkip+param, callPndTabSize, callPndTab read-without-use). 2. CalculatePushedArgSizeAt threw "Unsupported gc transition type" (InvalidOperationException, HRESULT 0x80131509) whenever an ESP-frame walk hit a CalleeSavedRegister transition (emitted by the partial- interrupt no-EBP decoder, case 7 / 0x04). Native scanArgRegTable treats this tag as informational (no effect on outgoing-arg depth); the cDAC switch was missing the case so every ESP-frame stack with a callee-saved-reg tag aborted GetStackReferences with hr=0x80131509. This was the source of 18-70 [FAIL] entries per debuggee in CI. 3. AddressFromGCRefMapPos used the same forward-from-FirstGCRefMapSlot formula on every architecture, but x86's TransitionBlock lays out its two argument registers (EDX/ECX) backward via ENUM_ARGUMENT_REGISTERS_BACKWARD. Native OffsetFromGCRefMapPos (frames.cpp) reverses pos 0/1 within the arg-regs area on x86. Without this fix, ExternalMethodFrame GCRefMap-driven scans reported the wrong arg-reg slot for the first two positions. Stack-arg positions (pos >= 2) remain forward, matching native. Local PInvoke debuggee under DOTNET_CdacStress=0x001: Before fix #1+#2: 70 fail / 64926 matched / 0 mismatched (every [FAIL] was an InvalidOperationException, not a real mismatch). After #1+#2: 2 fail / 66250 matched / 2 mismatched. After all three: 2 fail (remaining is a separate x86 GCRefMap decode bug in pos >= 2 stack args, tracked as follow-up). 5 of 9 debuggees now report 0 failures and 0 mismatches.
) Fixes dotnet#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
…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
…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
…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>
Depends on: dotnet#108939
Changes
ExecutionManagercontract version to2ExecutionManager_1toExecutionManagerBaseExecutionManager_2