66
77using namespace xamarin ::android;
88
9- void BridgeProcessing ::initialize_on_runtime_init (JNIEnv *env, jclass runtimeClass) noexcept
9+ void BridgeProcessingShared ::initialize_on_runtime_init (JNIEnv *env, jclass runtimeClass) noexcept
1010{
1111 abort_if_invalid_pointer_argument (env, " env" );
1212 abort_if_invalid_pointer_argument (runtimeClass, " runtimeClass" );
@@ -17,7 +17,7 @@ void BridgeProcessing::initialize_on_runtime_init (JNIEnv *env, jclass runtimeCl
1717 abort_unless (GCUserPeer_class != nullptr && GCUserPeer_ctor != nullptr , " Failed to load mono.android.GCUserPeer!" );
1818}
1919
20- BridgeProcessing::BridgeProcessing (MarkCrossReferencesArgs *args) noexcept
20+ BridgeProcessingShared::BridgeProcessingShared (MarkCrossReferencesArgs *args) noexcept
2121 : env{ OSBridge::ensure_jnienv () },
2222 cross_refs{ args }
2323{
@@ -34,15 +34,15 @@ BridgeProcessing::BridgeProcessing (MarkCrossReferencesArgs *args) noexcept
3434 }
3535}
3636
37- void BridgeProcessing ::process () noexcept
37+ void BridgeProcessingShared ::process () noexcept
3838{
3939 prepare_for_java_collection ();
4040 GCBridge::trigger_java_gc (env);
4141 cleanup_after_java_collection ();
4242 log_gc_summary ();
4343}
4444
45- void BridgeProcessing ::prepare_for_java_collection () noexcept
45+ void BridgeProcessingShared ::prepare_for_java_collection () noexcept
4646{
4747 // Before looking at xrefs, scan the SCCs. During collection, an SCC has to behave like a
4848 // single object. If the number of objects in the SCC is anything other than 1, the SCC
@@ -75,7 +75,7 @@ void BridgeProcessing::prepare_for_java_collection () noexcept
7575 }
7676}
7777
78- void BridgeProcessing ::prepare_scc_for_java_collection (size_t scc_index, const StronglyConnectedComponent &scc) noexcept
78+ void BridgeProcessingShared ::prepare_scc_for_java_collection (size_t scc_index, const StronglyConnectedComponent &scc) noexcept
7979{
8080 // Count == 0 case: Some SCCs might have no IGCUserPeers associated with them, so we must create one
8181 if (scc.Count == 0 ) {
@@ -93,7 +93,7 @@ void BridgeProcessing::prepare_scc_for_java_collection (size_t scc_index, const
9393 add_circular_references (scc);
9494}
9595
96- CrossReferenceTarget BridgeProcessing ::select_cross_reference_target (size_t scc_index) noexcept
96+ CrossReferenceTarget BridgeProcessingShared ::select_cross_reference_target (size_t scc_index) noexcept
9797{
9898 const StronglyConnectedComponent &scc = cross_refs->Components [scc_index];
9999
@@ -108,7 +108,7 @@ CrossReferenceTarget BridgeProcessing::select_cross_reference_target (size_t scc
108108}
109109
110110// caller must ensure that scc.Count > 1
111- void BridgeProcessing ::add_circular_references (const StronglyConnectedComponent &scc) noexcept
111+ void BridgeProcessingShared ::add_circular_references (const StronglyConnectedComponent &scc) noexcept
112112{
113113 auto get_control_block = [&scc](size_t index) -> JniObjectReferenceControlBlock& {
114114 abort_unless (scc.Contexts [index] != nullptr , " Context in SCC must not be null" );
@@ -142,7 +142,7 @@ void BridgeProcessing::add_circular_references (const StronglyConnectedComponent
142142 }
143143}
144144
145- void BridgeProcessing ::add_cross_reference (size_t source_index, size_t dest_index) noexcept
145+ void BridgeProcessingShared ::add_cross_reference (size_t source_index, size_t dest_index) noexcept
146146{
147147 CrossReferenceTarget from = select_cross_reference_target (source_index);
148148 CrossReferenceTarget to = select_cross_reference_target (dest_index);
@@ -152,11 +152,15 @@ void BridgeProcessing::add_cross_reference (size_t source_index, size_t dest_ind
152152 }
153153}
154154
155- bool BridgeProcessing ::add_reference (jobject from, jobject to) noexcept
155+ bool BridgeProcessingShared ::add_reference (jobject from, jobject to) noexcept
156156{
157157 abort_if_invalid_pointer_argument (from, " from" );
158158 abort_if_invalid_pointer_argument (to, " to" );
159159
160+ if (maybe_call_gc_user_peerable_add_managed_reference (env, from, to)) {
161+ return true ;
162+ }
163+
160164 jclass java_class = env->GetObjectClass (from);
161165 jmethodID add_method_id = env->GetMethodID (java_class, " monodroidAddReference" , " (Ljava/lang/Object;)V" );
162166
@@ -173,7 +177,7 @@ bool BridgeProcessing::add_reference (jobject from, jobject to) noexcept
173177 return true ;
174178}
175179
176- void BridgeProcessing ::clear_references_if_needed (const HandleContext &context) noexcept
180+ void BridgeProcessingShared ::clear_references_if_needed (const HandleContext &context) noexcept
177181{
178182 if (context.is_collected ()) {
179183 return ;
@@ -193,10 +197,14 @@ void BridgeProcessing::clear_references_if_needed (const HandleContext &context)
193197 control_block->refs_added = 0 ;
194198}
195199
196- void BridgeProcessing ::clear_references (jobject handle) noexcept
200+ void BridgeProcessingShared ::clear_references (jobject handle) noexcept
197201{
198202 abort_if_invalid_pointer_argument (handle, " handle" );
199203
204+ if (maybe_call_gc_user_peerable_clear_managed_references (env, handle)) {
205+ return ;
206+ }
207+
200208 jclass java_class = env->GetObjectClass (handle);
201209 jmethodID clear_method_id = env->GetMethodID (java_class, " monodroidClearReferences" , " ()V" );
202210
@@ -211,7 +219,7 @@ void BridgeProcessing::clear_references (jobject handle) noexcept
211219 env->CallVoidMethod (handle, clear_method_id);
212220}
213221
214- void BridgeProcessing ::take_global_ref (HandleContext &context) noexcept
222+ void BridgeProcessingShared ::take_global_ref (HandleContext &context) noexcept
215223{
216224 abort_unless (context.control_block != nullptr , " Control block must not be null" );
217225 abort_unless (context.control_block ->handle_type == JNIWeakGlobalRefType, " Expected weak global reference type for handle" );
@@ -231,7 +239,7 @@ void BridgeProcessing::take_global_ref (HandleContext &context) noexcept
231239 env->DeleteWeakGlobalRef (weak);
232240}
233241
234- void BridgeProcessing ::take_weak_global_ref (const HandleContext &context) noexcept
242+ void BridgeProcessingShared ::take_weak_global_ref (const HandleContext &context) noexcept
235243{
236244 abort_unless (context.control_block != nullptr , " Control block must not be null" );
237245 abort_unless (context.control_block ->handle_type == JNIGlobalRefType, " Expected global reference type for handle" );
@@ -249,7 +257,7 @@ void BridgeProcessing::take_weak_global_ref (const HandleContext &context) noexc
249257 env->DeleteGlobalRef (handle);
250258}
251259
252- void BridgeProcessing ::cleanup_after_java_collection () noexcept
260+ void BridgeProcessingShared ::cleanup_after_java_collection () noexcept
253261{
254262 for (size_t i = 0 ; i < cross_refs->ComponentCount ; i++) {
255263 const StronglyConnectedComponent &scc = cross_refs->Components [i];
@@ -267,7 +275,7 @@ void BridgeProcessing::cleanup_after_java_collection () noexcept
267275 }
268276}
269277
270- void BridgeProcessing ::abort_unless_all_collected_or_all_alive (const StronglyConnectedComponent &scc) noexcept
278+ void BridgeProcessingShared ::abort_unless_all_collected_or_all_alive (const StronglyConnectedComponent &scc) noexcept
271279{
272280 if (scc.Count == 0 ) {
273281 return ;
@@ -306,7 +314,7 @@ void CrossReferenceTarget::mark_refs_added_if_needed () noexcept
306314}
307315
308316[[gnu::always_inline]]
309- void BridgeProcessing ::log_missing_add_references_method ([[maybe_unused]] jclass java_class) noexcept
317+ void BridgeProcessingShared ::log_missing_add_references_method ([[maybe_unused]] jclass java_class) noexcept
310318{
311319 log_error (LOG_DEFAULT, " Failed to find monodroidAddReferences method" );
312320#if DEBUG
@@ -322,7 +330,7 @@ void BridgeProcessing::log_missing_add_references_method ([[maybe_unused]] jclas
322330}
323331
324332[[gnu::always_inline]]
325- void BridgeProcessing ::log_missing_clear_references_method ([[maybe_unused]] jclass java_class) noexcept
333+ void BridgeProcessingShared ::log_missing_clear_references_method ([[maybe_unused]] jclass java_class) noexcept
326334{
327335 log_error (LOG_DEFAULT, " Failed to find monodroidClearReferences method" );
328336#if DEBUG
@@ -338,7 +346,7 @@ void BridgeProcessing::log_missing_clear_references_method ([[maybe_unused]] jcl
338346}
339347
340348[[gnu::always_inline]]
341- void BridgeProcessing ::log_weak_to_gref (jobject weak, jobject handle) noexcept
349+ void BridgeProcessingShared ::log_weak_to_gref (jobject weak, jobject handle) noexcept
342350{
343351 if (handle != nullptr ) {
344352 OSBridge::_monodroid_gref_log_new (weak, OSBridge::get_object_ref_type (env, weak),
@@ -358,7 +366,7 @@ void BridgeProcessing::log_weak_to_gref (jobject weak, jobject handle) noexcept
358366}
359367
360368[[gnu::always_inline]]
361- void BridgeProcessing ::log_weak_ref_collected (jobject weak) noexcept
369+ void BridgeProcessingShared ::log_weak_ref_collected (jobject weak) noexcept
362370{
363371 if (Logger::gc_spew_enabled ()) [[likely]] {
364372 return ;
@@ -369,7 +377,7 @@ void BridgeProcessing::log_weak_ref_collected (jobject weak) noexcept
369377}
370378
371379[[gnu::always_inline]]
372- void BridgeProcessing ::log_take_weak_global_ref (jobject handle) noexcept
380+ void BridgeProcessingShared ::log_take_weak_global_ref (jobject handle) noexcept
373381{
374382 if (!Logger::gref_log ()) [[likely]] {
375383 return ;
@@ -379,29 +387,29 @@ void BridgeProcessing::log_take_weak_global_ref (jobject handle) noexcept
379387}
380388
381389[[gnu::always_inline]]
382- void BridgeProcessing ::log_weak_gref_new (jobject handle, jobject weak) noexcept
390+ void BridgeProcessingShared ::log_weak_gref_new (jobject handle, jobject weak) noexcept
383391{
384392 OSBridge::_monodroid_weak_gref_new (handle, OSBridge::get_object_ref_type (env, handle),
385393 weak, OSBridge::get_object_ref_type (env, weak),
386394 " finalizer" , gettid (), " at [[clr-gc:take_weak_global_ref]]" , 0 );
387395}
388396
389397[[gnu::always_inline]]
390- void BridgeProcessing ::log_gref_delete (jobject handle) noexcept
398+ void BridgeProcessingShared ::log_gref_delete (jobject handle) noexcept
391399{
392400 OSBridge::_monodroid_gref_log_delete (handle, OSBridge::get_object_ref_type (env, handle),
393401 " finalizer" , gettid (), " at [[clr-gc:take_weak_global_ref]]" , 0 );
394402}
395403
396404[[gnu::always_inline]]
397- void BridgeProcessing ::log_weak_ref_delete (jobject weak) noexcept
405+ void BridgeProcessingShared ::log_weak_ref_delete (jobject weak) noexcept
398406{
399407 OSBridge::_monodroid_weak_gref_delete (weak, OSBridge::get_object_ref_type (env, weak),
400408 " finalizer" , gettid (), " at [[clr-gc:take_global_ref]]" , 0 );
401409}
402410
403411[[gnu::always_inline]]
404- void BridgeProcessing ::log_gc_summary () noexcept
412+ void BridgeProcessingShared ::log_gc_summary () noexcept
405413{
406414 if (!Logger::gc_spew_enabled ()) [[likely]] {
407415 return ;
0 commit comments