Uh oh!
There was an error while loading. Please reload this page.
Remove local strings from timing - #12513
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the shared native fast-timing implementation to stop using dynamic_local_string for formatting and option parsing, moving toward fixed-buffer (char[]) handling to reduce reliance on the local-string hierarchy and eventually C++ runtime dependencies in shared native code.
Changes:
- Switch timing option retrieval/parsing (
debug.mono.timing) to fixed buffers and in-place C-string tokenization. - Replace timing log/event message construction with fixed
chararrays andsnprintf, returning event descriptions as string literals. - Add
AndroidSystem::monodroid_get_system_propertyoverloads that write directly into caller-providedchar[]buffers (MonoVM and CLR variants).
Show a summary per file
| File | Description |
|---|---|
| src/native/mono/runtime-base/android-system.hh | Adds char[] overload for system property retrieval on the MonoVM side. |
| src/native/common/runtime-base/timing-internal.cc | Migrates timing option parsing, log message formatting, and output path building to fixed buffers. |
| src/native/common/include/runtime-base/timing-internal.hh | Updates timing message formatting helpers to use fixed buffers and snprintf. |
| src/native/clr/include/runtime-base/android-system.hh | Adds char[] overload for system property retrieval on the CLR side. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
6b89b87 to
1e2809eCompare176c7d7 to
75a294aCompared9fb4b3 to
f02f1d2Comparef02f1d2 to
17bbadbCompareCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The fixed timing buffers reduce libmonodroid.so from 1,184,800 to 1,094,848 bytes. Refresh all four affected CoreCLR package baselines using build 1566719 output. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assembly store timing metadata no longer uses the local-string types. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Allocate timing metadata to its exact size instead of treating the former local-string stack threshold as a maximum. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use malloc only when assembly timing information exceeds the former local-string stack threshold. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Retry timing metadata formatting with exact heap storage only when the sensible stack buffer is insufficient. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Route assembly timing heap-buffer cleanup through the same helper as temporary path buffers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rely on free(nullptr) and name the stack-backed timing buffer explicitly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eliminate the separate heap pointer and free assembly timing storage only when it differs from the stack buffer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
17bbadb to
2a66e35Comparesimonrozsival
commented
Aug 26, 2026
/review |
✅ Android PR Reviewer completed successfully!
|
There was a problem hiding this comment.
The new pointer/stack-buffer ownership paths and TMPDIR/file cleanup are sound, but file-based timing output now inherits the logcat size limit and can emit truncated, unparsable records. CI build 1568587 is still in progress; all completed checks are currently passing.
Generated by Android PR Reviewer for #12513 · gpt56 · 287.3 AIC · ⌖ 8.87 AIC · ⊞ 25.7K
Comment /review to run again
Uh oh!
There was an error while loading. Please reload this page.
`format_message()` formatted every timing record into a fixed `char [MAX_LOGCAT_MESSAGE_LENGTH]` buffer, so a record longer than 1023 bytes was silently truncated. Because `more_info` is formatted *before* the `; elapsed: ...` suffix, a long enough value dropped the timing data itself and produced an unparseable record. `more_info` is unbounded -- `add_more_info (const char*)` uses `strlen()` and is passed managed type names -- and `dump()` is shared by `dump_to_logcat()` and `dump_to_file()`, so file output was capped for no reason. Split the formatting in two, following the existing `format_joined_path()`/`join_paths()` convention: `format_message()` now returns the message length, or the negative required capacity when the buffer is too small, and `build_message()` retries into a `malloc()`ed buffer in that case. Callers free the result only when it differs from the stack buffer, so the common case stays allocation-free. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0a35a0db-502d-48c0-8468-e73b5dd0ab2e
`FastTiming::add_more_info` had an overload taking a `char (&)[Size]` together with the `int` returned by `snprintf`. That return value is the length the message *would* have had, not the length that was written, so the overload clamped it to `Size - 1` to avoid handing out a length that runs past the end of the buffer. The clamp was correct, but it meant an oversized message was silently truncated, and the three CoreCLR callers each needed a 1023-byte stack buffer to format into. Since `more_info` is stored as a `std::string` anyway, that intermediate buffer bought nothing. All three messages are just an assembly name followed by a constant suffix, so add an overload taking the two parts as `std::string_view`s and building the string directly. The length is then exact by construction, there is no buffer to overflow and nothing to truncate. The last caller of the array-size overload is in `monodroid-glue.cc`, where the buffer is exactly sized for a base-10 `size_t` and so cannot truncate. It now passes the length explicitly and asserts that it fits, which lets the array-size overload go away entirely. `add_more_info` implementations now share a `store_more_info` helper, which also takes ownership of the string so it isn't leaked when there is no open timing sequence. No change in libc++ usage (76 undefined references before and after). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0a35a0db-502d-48c0-8468-e73b5dd0ab2e
Uh oh!
There was an error while loading. Please reload this page.
Summary
Remove local-string dependencies from native timing code while preserving complete timing metadata and records. Bounded values continue to use fixed stack buffers; unbounded assembly names and timing messages grow to exact-size heap storage only when needed.
This reduces
libmonodroid.sosize without imposing the former local-string or logcat buffer limits on timing output.Changes
dynamic_local_stringusage with fixed arrays for genuinely bounded Android properties, logcat messages, and integer formattingadd_more_info()overloads so CoreCLR assembly names and constant suffixes are stored directly without 1023-byte temporary buffers or silent truncationmore_infoownership instore_more_info(), including cleanup when no timing sequence is openmalloc()storage for oversized namesmore_infovalues from truncating the elapsed-time suffix or producing unparseable file outputjoin_paths()helper for timing outputTMPDIR, and close the output file when timing-file setup failsstrings.hhdependencies1566719;libmonodroid.sodecreased from 1,184,800 to 1,094,848 bytesValidation
libc++undefined references remain unchanged at 76 before and after1566719