Skip to content

[native] Use a raw pointer for the CoreCLR host's Timing instance - #12540

Closed
simonrozsival wants to merge 2 commits into
dev/simonrozsival/clr-remove-std-formatfrom
dev/simonrozsival/clr-timing-raw-pointer
Closed

[native] Use a raw pointer for the CoreCLR host's Timing instance#12540
simonrozsival wants to merge 2 commits into
dev/simonrozsival/clr-remove-std-formatfrom
dev/simonrozsival/clr-timing-raw-pointer

Conversation

@simonrozsival

Copy link
Copy Markdown
Member

Part of #12533.

Host::_timing is a process-lifetime singleton: it is created once, when fast timing is enabled, and never released. Holding it in a std::shared_ptr bought us nothing but a control block allocation and atomic refcount traffic on every get_timing () call — the call sites even bound the returned shared pointer to a const& to dodge the refcount, with a comment apologising for it:

// Technically a reference here is against the idea of shared pointers, but// in this instance it's fine since we know we won't be storing the pointer// and this way things are slightly faster.
std::shared_ptr<Timing> const &timing = Host::get_timing ();

Store a plain Timing* instead.

Effect

This removes the last std::shared_ptr from the CoreCLR host, dropping all five std::__ndk1::__shared_weak_count references plus one static initialisation guard pair:

undefined libc++ symbols in libnet-android.release-static-release.a
before55
after48

For reference, the NativeAOT host is already at 0, which is the target for CoreCLR.

The allocation itself is deliberately unchanged — removing the remaining new/delete calls is a separate cause, tracked in #12533.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR is part of #12533 and continues the effort to remove libc++ dependencies from the CoreCLR host by eliminating std::shared_ptr usage for the Timing singleton and replacing remaining C++-stdlib-heavy formatting/logging patterns (e.g., std::format, std::string_view-based formatting) with snprintf/printf-style logging and fixed-buffer helpers. It also adjusts runtime pack composition so NativeAOT no longer ships/links libc++ archives, while CoreCLR continues to.

Changes:

  • Replace the CoreCLR host’s Host::_timing from std::shared_ptr<Timing> to a raw Timing* process-lifetime singleton.
  • Reduce libc++ surface area by removing std::format usage across several native host/runtime components, switching to snprintf + log_*f APIs and fixed-buffer formatting helpers.
  • Adjust packaging/build logic so libc++/unwind archives are treated as C++ assets and shipped only for CoreCLR; update APK baseline descriptors to reflect size changes.
Show a summary per file
FileDescription
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.CoreCLR.R8.apkdescUpdate baseline package contents/sizes after native host changes.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.CoreCLR.apkdescUpdate baseline package contents/sizes after native host changes.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.CoreCLR.R8.apkdescUpdate baseline package contents/sizes after native host changes.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.CoreCLR.apkdescUpdate baseline package contents/sizes after native host changes.
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targetsStop linking/shipping libc++ for NativeAOT; keep libstdc++compat.a rationale documented.
src/native/native.targetsRuntime pack file selection: ship libc++ archives only for CoreCLR.
src/native/mono/shared/log_types.hhRemove std::string_view logging helper to avoid C++ stdlib dependencies.
src/native/mono/shared/helpers.ccAdd Helpers::abort_applicationf to replace std::format-based abort paths.
src/native/mono/runtime-base/android-system.hhAdd fixed-buffer system-property retrieval helper overloads.
src/native/mono/runtime-base/android-system.ccImplement fixed-buffer system-property retrieval to avoid dynamic string types.
src/native/mono/monodroid/monodroid-glue.ccReplace dynamic string building with stack/heap formatting helpers for timing “more info”.
src/native/common/runtime-base/timing-internal.ccReplace std::format/string-heavy timing output with snprintf/buffer formatting; improve TMPDIR handling.
src/native/common/include/runtime-base/timing-internal.hhRefactor timing message formatting to fixed buffers and explicit ownership of “more info”.
src/native/common/include/runtime-base/system-loadlibrary-wrapper.hhSwitch std::format-style logging to log_*f APIs.
src/native/common/include/runtime-base/mainthread-dso-loader.hhRemove <format>, convert to abort_applicationf/log_*f, and make pipe write EINTR-safe.
src/native/common/include/runtime-base/dso-loader.hhConvert std::format-style logging to log_*f with length-limited string formatting.
src/native/clr/runtime-base/util.ccReplace dynamic strings with stack/heap buffer pattern for directory creation.
src/native/clr/runtime-base/logger.ccRefactor log-category parsing to use std::string_view and fixed-buffer property reads.
src/native/clr/runtime-base/android-system.ccReplace std::format logging and refactor DSO-path building to fixed-buffer formatting.
src/native/clr/runtime-base/android-system-shared.ccRefactor system property reads to fixed buffers and remove dynamic string helpers.
src/native/clr/pinvoke-override/precompiled.ccRemove <format> and switch abort/logging paths to abort_applicationf/log_*f.
src/native/clr/include/shared/log_types.hhRemove stdlib-heavy log macro definitions, leaving shared log function surface.
src/native/clr/include/runtime-base/util.hhAdd fixed-buffer helpers for DSO name formatting.
src/native/clr/include/runtime-base/monodroid-dl.hhConvert logging to log_*f and remove std::format usage.
src/native/clr/include/runtime-base/logger.hhRemove dependency on strings helper types and adjust category parsing signature.
src/native/clr/include/runtime-base/android-system.hhReplace dynamic-string system property reads with fixed-buffer overload; refactor override-dir formatting.
src/native/clr/include/host/typemap.hhReplace std::string_view constants with const char* for debug labeling.
src/native/clr/include/host/pinvoke-override-impl.hhUse new DSO-name formatting helper and convert logging to log_*f.
src/native/clr/include/host/os-bridge.hhInclude shared C++ utility header for common helpers.
src/native/clr/include/host/host.hhSwitch Timing singleton storage from std::shared_ptr to raw pointer.
src/native/clr/include/host/assembly-store.hhRemove unused strings helper include.
src/native/clr/host/typemap.ccReplace std::format logging and dynamic string building with fixed-buffer formatting helpers.
src/native/clr/host/internal-pinvokes-clr.ccUpdate timing calls to use raw Timing* from host.
src/native/clr/host/host.ccReplace std::format logging, switch timing singleton allocation to new Timing(), and convert many logs to log_*f.
src/native/clr/host/fastdev-assemblies.ccReplace std::format abort/logging with abort_applicationf/log_*f.
src/native/clr/host/bridge-processing.ccConvert GC summary/logging to log_*f.
src/native/clr/host/assembly-store.ccRemove std::format usage and replace with snprintf/log_*f, including store-id formatting.
build-tools/scripts/Ndk.targetsReclassify libc++/unwind redistributables as C++ assets for selective packing.
build-tools/create-packs/Microsoft.Android.Runtime.projPack libc++/unwind assets only for CoreCLR runtime packs.

Review details

  • Files reviewed: 39/39 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment threadsrc/native/clr/runtime-base/android-system-shared.cc Outdated
Comment threadsrc/native/clr/include/host/host.hh
@simonrozsival
simonrozsivalforce-pushed the dev/simonrozsival/clr-timing-raw-pointer branch from f1188a8 to 646ecfcCompareAugust 27, 2026 15:47
@simonrozsival
simonrozsivalforce-pushed the dev/simonrozsival/clr-remove-std-format branch from 0d6ad82 to 03be5c7CompareAugust 27, 2026 15:47
simonrozsivaland others added 2 commits August 27, 2026 18:08
`Host::_timing` is a process-lifetime singleton that is created once, when
fast timing is enabled, and never released. Holding it in a
`std::shared_ptr` bought us nothing but a control block allocation and
atomic refcount traffic on every `get_timing ()` call - the call sites even
bound the returned shared pointer to a `const&` to avoid the refcount, with
a comment apologising for it.
Store a plain `Timing*` instead. This removes the last `std::shared_ptr`
from the CoreCLR host and drops five `std::__ndk1::__shared_weak_count`
references (plus a static initialisation guard) from
`libnet-android.release-static-release.a`, taking the host from 55 to 48
undefined libc++ symbols.
The allocation itself is unchanged; removing the remaining `new`/`delete`
calls is tracked separately.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0a35a0db-502d-48c0-8468-e73b5dd0ab2e
Document that `Host::_timing` is intentionally never freed, so that the
missing `delete` isn't mistaken for a leak and "fixed" later.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0a35a0db-502d-48c0-8468-e73b5dd0ab2e
@simonrozsival
simonrozsivalforce-pushed the dev/simonrozsival/clr-remove-std-format branch from 03be5c7 to f48725dCompareAugust 27, 2026 16:09
@simonrozsival
simonrozsivalforce-pushed the dev/simonrozsival/clr-timing-raw-pointer branch from 646ecfc to cc97080CompareAugust 27, 2026 16:09
@simonrozsival

Copy link
Copy Markdown
MemberAuthor

Superseded by #12545.

#12545 removes Host::_timing entirely — the instance became a static inline Timing and get_timing () returns a reference — so the std::shared_ptr this PR was replacing with a raw pointer disappears there instead. The raw pointer was only ever an intermediate state.

Nothing is lost by dropping this: rebasing the rest of the stack straight onto #12534 still lands at 38libc++ refs, the same as with this PR in the chain. The progression is now 55 → 47 (#12541) → 38 (#12545) instead of 55 → 48 → 40 → 38.

@simonrozsival

Copy link
Copy Markdown
MemberAuthor

Superseded by #12545 — see the earlier comment. The stack is now #12534#12541#12545.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@simonrozsival