') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Suboptimal code generated for even a trivial ValueConverter · Issue #85570 · dotnet/runtime · GitHub
Skip to content

Suboptimal code generated for even a trivial ValueConverter #85570

Description

@hez2010

Description

I'm seeing suboptimal code generated for ValueConverters even when what the converter does is trivial.

For example,

classProgram{privatestaticreadonlyFoofoo=new();privatestaticreadonlyCultureInfoculture=CultureInfo.CurrentCulture;publicintTest(){varx=3;vary=(int)foo.Convert(x,typeof(int),null,culture);returny;}}interfaceIValueConverter{objectConvert(objectvalue,TypetargetType,object?parameter,CultureInfo?culture);}sealedclassFoo:IValueConverter{publicobjectConvert(objectvalue,TypetargetType,object?parameter,CultureInfo?culture){return(int)value+1;}}

The codegen:

; Assembly listing for method Program:Test():int:this; Emitting BLENDED_CODE for X64 CPU with AVX - Windows; optimized code; rsp based frame; partially interruptible; No PGO data; 0 inlinees with PGO data; 1 single block inlinees; 0 inlinees without PGO dataG_M000_IG01: ;; offset=0000Hpushrdipushrsisubrsp,40G_M000_IG02: ;; offset=0006Hmovrsi,0x7FF7BD400858movrcx,rsicall CORINFO_HELP_NEWSFASTmovrdi,raxtest byte ptr [(reloc 0x7ff7bd6f9344)],1je SHORT G_M000_IG05G_M000_IG03: ;; offset=0024Hmovrcx,0x23591401DA8movrcx, gword ptr [rcx]mov dword ptr [rdi+08H],3cmp byte ptr [rcx],clmovrcx,rsicall CORINFO_HELP_NEWSFASTmovecx, dword ptr [rdi+08H]incecxmov dword ptr [rax+08H],ecxmoveax, dword ptr [rax+08H]G_M000_IG04: ;; offset=004DHaddrsp,40poprsipoprdiretG_M000_IG05: ;; offset=0054Hmovrcx,0x7FF7BD6F9310movedx,4call CORINFO_HELP_GETSHARED_NONGCSTATIC_BASEjmp SHORT G_M000_IG03; Total bytes of code 106

This is important because ValueConverters are heavily used in Desktop apps that use XAML (WPF, UWP, MAUI and etc.), and we want to minimize the overhead caused by ValueConverters.

Expected codegen:

moveax,4ret

Configuration

.NET 8 preview 3

Metadata

Metadata

Assignees

Labels

Priority:2Work that is important, but not critical for the releasearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMItenet-performancePerformance related issue

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions