-
Notifications
You must be signed in to change notification settings - Fork 565
[NativeAOT] Move GC bridge processing from C++ to C# #10748
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add BridgeProcessing.cs with managed implementation of bridge processing - Add new native methods for managed processing mode - Update ManagedValueManager to use managed processing loop - Update gc-bridge.hh with new managed processing APIs Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Removed files: - src/native/clr/host/bridge-processing.cc - src/native/clr/include/host/bridge-processing.hh - src/native/clr/include/host/bridge-processing-shared.hh - src/native/nativeaot/host/bridge-processing.cc - src/native/nativeaot/include/host/bridge-processing.hh Updated files to remove references to deleted files: - src/native/clr/host/CMakeLists.txt - src/native/nativeaot/host/CMakeLists.txt - src/native/clr/host/gc-bridge.cc - src/native/nativeaot/host/host.cc Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
- Remove clr_initialize_gc_bridge P/Invoke (old callback mode never used) - Remove initialize_callback() function from gc-bridge.hh - Remove bridge_processing() function (native background thread loop) - Remove bridge_processing_started_callback and bridge_processing_finished_callback - Remove bridge_processing_thread and managed_processing_mode flag - Remove unused includes (thread, shared_mutex, unordered_map) - Remove BridgeProcessingStartedFtn and BridgeProcessingFinishedFtn typedefs This eliminates 2 reverse p/invokes per GC cycle that were never used. Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
…idge The autogenerated file was out of sync with the source after removing clr_initialize_gc_bridge and adding the new managed processing mode functions. Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
src/Mono.Android/Microsoft.Android.Runtime/ManagedValueManager.cs
Outdated
Show resolved
Hide resolved
- Pass UCO callback to native during initialization - Native mark_cross_references calls the UCO callback directly - UCO stores args in ConcurrentQueue and signals SemaphoreSlim - C# background thread waits on semaphore and processes from queue - Remove clr_gc_bridge_wait_for_processing P/Invoke - Remove semaphore and atomic from C++ code - Regenerate pinvoke-tables.include Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
…omment - Call Runtime.gc() directly from C# via JNI instead of calling native code - Remove clr_gc_bridge_trigger_java_gc P/Invoke and native implementation - Remove unnecessary comment from host.cc line 66 - Simplify native GCBridge by removing Runtime instance caching - Regenerate pinvoke-tables.include (now 24 internal p/invokes) Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
- Remove explicit Cdecl calling convention from UnmanagedCallersOnly and function pointers (Cdecl is default on Linux/Android) - Restore bridgeProcessingSemaphore for WaitForGCBridgeProcessing - Convert BridgeProcessing.Initialize to static constructor using RuntimeFeature - Replace CrossReferenceTarget struct with ValueTuple - Rename peer variable to peerToDispose for clarity - Simplify AddReference/ClearReferences by removing outer try-catch blocks Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
simonrozsival
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot one thing we're missing and which can be useful is the detailed logging -- if enabled!
I suggest adding static BridgeProcessingLogger? s_logger which will be initialized based on the Android.Runtime.Logger.LogGC and other flags. Migrate the same tags and formatting from bridge-processing.cc.
- Add BridgeProcessingLogger class for detailed GC bridge logging - Migrate logging from C++ bridge-processing.cc (same tags and formatting) - Enable logging based on Logger.LogGC and Logger.LogGlobalRef flags - Replace s_isNativeAOT field with !RuntimeFeature.IsCoreClrRuntime checks - Log: missing method errors, weak/gref operations, GC summary Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Added |
src/Mono.Android/Microsoft.Android.Runtime/ManagedValueManager.cs
Outdated
Show resolved
Hide resolved
simonrozsival
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot address review comments. try to clean up the code and remove unnecessary or verbose comments.
- Remove unused System.Threading.Tasks using from ManagedValueManager.cs - Remove unused System.Threading using from BridgeProcessing.cs - Revert symbol name to shorter clr_gc_bridge_init - Move Java GC triggering to separate JavaGCTrigger.cs - Move BridgeProcessingLogger to separate file with only unsafe method marked - Simplify peerToDispose variable Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
simonrozsival
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot we're getting there! address this next round of review comments.
Add CS0436 to NoWarn in Mono.Android.csproj. This warning occurs because RuntimeFeature.cs is compiled into both Mono.Android and Mono.Android.Runtime assemblies via linked file. The warning is benign - using the local definition is the intended behavior. Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
…rable helpers - Rename clr_gc_bridge_init back to clr_initialize_gc_bridge - Remove unnecessary comment from internal-pinvokes.hh - Move GCUserPeerable helpers to JavaGCTrigger class - Remove runtime check from JavaGCTrigger.Trigger (static ctor guarantees init) - Suppress CS0436 warning for RuntimeFeature type conflict - Regenerate pinvoke-tables.include with new hash values Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
simonrozsival
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot address these comments
…te tables - Add BridgeProcessingLogger.cs and BridgeProcessingJniHelper.cs to Mono.Android.csproj - Rename JavaGCTrigger to BridgeProcessingJniHelper - Update BridgeProcessing.cs to use the renamed class - Regenerate pinvoke-tables.include (was out of sync) - Remove CS0436 from NoWarn (use the warning to catch issues) Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
simonrozsival
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot address this review
| { | ||
| // Count == 0 case: Some SCCs might have no IGCUserPeers associated with them, so we must create one | ||
| if (scc.Count == 0) { | ||
| var newObject = s_GCUserPeerClass!.NewObject (s_GCUserPeerCtor!, null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect this to be also moved to the JNI helper class.
| // Fall back to reflection-based approach | ||
| var fromClassRef = JniEnvironment.Types.GetObjectClass (from); | ||
| using var fromClass = new JniType (ref fromClassRef, JniObjectReferenceOptions.CopyAndDispose); | ||
|
|
||
| JniMethodInfo addMethod; | ||
| try { | ||
| addMethod = fromClass.GetInstanceMethod ("monodroidAddReference", "(Ljava/lang/Object;)V"); | ||
| } catch (Java.Lang.NoSuchMethodError) { | ||
| s_logger?.LogMissingAddReferencesMethod (fromClass); | ||
| return false; | ||
| } | ||
|
|
||
| JniArgumentValue* args = stackalloc JniArgumentValue[1]; | ||
| args[0] = new JniArgumentValue (to); | ||
| JniEnvironment.InstanceMethods.CallVoidMethod (from, addMethod, args); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect this to be moved to the JNI helper class as well
| } | ||
| } | ||
|
|
||
| public static void Trigger () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename this to TriggerJavaGC
clr_initialize_gc_bridge(keep original name)Summary
Architecture:
mark_cross_referencesjust signals semaphoreBridgeProcessing.Process()BridgeProcessingJniHelperclass)Code Organization:
BridgeProcessing.cs- Main processing logicBridgeProcessingLogger.cs- Detailed logging based on Logger.LogGC flagsBridgeProcessingJniHelper.cs- Java GC trigger + GCUserPeerable managed reference helpersOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.