@@ -42,9 +42,6 @@ const uint32_t OSBridge::NUM_GC_BRIDGE_TYPES = NUM_XA_GC_BRIDGE_TYPES + NUM_J
4242OSBridge::MonoJavaGCBridgeInfo OSBridge::mono_java_gc_bridge_info [NUM_GC_BRIDGE_TYPES];
4343
4444OSBridge::MonoJavaGCBridgeInfo OSBridge::empty_bridge_info = {
45- nullptr ,
46- nullptr ,
47- nullptr ,
4845 nullptr ,
4946 nullptr
5047};
@@ -76,9 +73,13 @@ OSBridge::clear_mono_java_gc_bridge_info ()
7673 for (uint32_t c = 0 ; c < NUM_GC_BRIDGE_TYPES; c++) {
7774 MonoJavaGCBridgeInfo *info = &mono_java_gc_bridge_info [c];
7875 info->klass = nullptr ;
79- info->handle = nullptr ;
80- info->handle_type = nullptr ;
81- info->refs_added = nullptr ;
76+ auto control_block = reinterpret_cast <JniObjectReferenceControlBlock*>(info->jniObjectReferenceControlBlock );
77+ if (control_block == nullptr ) [[unlikely]] {
78+ continue ;
79+ }
80+ control_block->handle = nullptr ;
81+ control_block->handle_type = 0 ;
82+ control_block->refs_added = 0 ;
8283 }
8384}
8485
@@ -102,6 +103,19 @@ OSBridge::get_gc_bridge_index (MonoClass *klass)
102103 : -1 ;
103104}
104105
106+ OSBridge::JniObjectReferenceControlBlock*
107+ OSBridge::get_gc_control_block_for_object (MonoObject *obj)
108+ {
109+ MonoJavaGCBridgeInfo *bridge_info = get_gc_bridge_info_for_object (obj);
110+ if (bridge_info == nullptr ) {
111+ return nullptr ;
112+ }
113+
114+ JniObjectReferenceControlBlock *control_block = nullptr ;
115+ mono_field_get_value (obj, bridge_info->jniObjectReferenceControlBlock , &control_block);
116+ return control_block;
117+ }
118+
105119OSBridge::MonoJavaGCBridgeInfo *
106120OSBridge::get_gc_bridge_info_for_class (MonoClass *klass)
107121{
@@ -459,11 +473,12 @@ OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj)
459473 jobject handle, weak;
460474 int type = JNIGlobalRefType;
461475
462- MonoJavaGCBridgeInfo *bridge_info = get_gc_bridge_info_for_object (obj);
463- if (bridge_info == nullptr )
476+ JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (obj);
477+ if (control_block == nullptr ) {
464478 return 0 ;
479+ }
465480
466- mono_field_get_value (obj, bridge_info ->handle , &weak);
481+ mono_field_get_value (obj, reinterpret_cast <MonoClassField*>(control_block ->handle ) , &weak);
467482 handle = env->NewGlobalRef (weak);
468483 if (gref_log) {
469484 fprintf (gref_log, " *try_take_global obj=%p -> wref=%p handle=%p\n " , obj, weak, handle);
@@ -476,8 +491,8 @@ OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj)
476491 " at [[gc:take_global_ref_jni]]" , 0 );
477492 } else if (Logger::gc_spew_enabled ()) [[unlikely]] {
478493 void *key_handle = nullptr ;
479- if (bridge_info-> key_handle ) {
480- mono_field_get_value (obj, bridge_info-> key_handle , &key_handle);
494+ if (control_block-> weak_handle ) {
495+ mono_field_get_value (obj, reinterpret_cast <MonoClassField*>(control_block-> weak_handle ) , &key_handle);
481496 }
482497
483498 MonoClass *klass = mono_object_get_class (obj);
@@ -491,8 +506,8 @@ OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj)
491506 free (message);
492507 }
493508
494- mono_field_set_value (obj, bridge_info ->handle , &handle);
495- mono_field_set_value (obj, bridge_info ->handle_type , &type);
509+ mono_field_set_value (obj, reinterpret_cast <MonoClassField*>(control_block ->handle ) , &handle);
510+ mono_field_set_value (obj, reinterpret_cast <MonoClassField*>(control_block ->handle_type ) , &type);
496511
497512 _monodroid_weak_gref_delete (weak, get_object_ref_type (env, weak),
498513 " finalizer" , gettid (), " at [[gc:take_global_ref_jni]]" , 0 );
@@ -507,11 +522,12 @@ OSBridge::take_weak_global_ref_jni (JNIEnv *env, MonoObject *obj)
507522 jobject handle, weak;
508523 int type = JNIWeakGlobalRefType;
509524
510- MonoJavaGCBridgeInfo *bridge_info = get_gc_bridge_info_for_object (obj);
511- if (bridge_info == nullptr )
525+ JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (obj);
526+ if (control_block == nullptr ) {
512527 return 0 ;
528+ }
513529
514- mono_field_get_value (obj, bridge_info ->handle , &handle);
530+ mono_field_get_value (obj, reinterpret_cast <MonoClassField*>(control_block ->handle ) , &handle);
515531 if (gref_log) {
516532 fprintf (gref_log, " *take_weak obj=%p; handle=%p\n " , obj, handle);
517533 fflush (gref_log);
@@ -522,8 +538,8 @@ OSBridge::take_weak_global_ref_jni (JNIEnv *env, MonoObject *obj)
522538 weak, get_object_ref_type (env, weak),
523539 " finalizer" , gettid (), " at [[gc:take_weak_global_ref_jni]]" , 0 );
524540
525- mono_field_set_value (obj, bridge_info ->handle , &weak);
526- mono_field_set_value (obj, bridge_info ->handle_type , &type);
541+ mono_field_set_value (obj, reinterpret_cast <MonoClassField*>(control_block ->handle ) , &weak);
542+ mono_field_set_value (obj, reinterpret_cast <MonoClassField*>(control_block ->handle_type ) , &type);
527543
528544 _monodroid_gref_log_delete (handle, get_object_ref_type (env, handle),
529545 " finalizer" , gettid (), " at [[gc:take_weak_global_ref_jni]]" , 0 );
@@ -558,13 +574,23 @@ OSBridge::gc_bridge_class_kind (MonoClass *klass)
558574mono_bool
559575OSBridge::gc_is_bridge_object (MonoObject *object)
560576{
561- void *handle;
577+ if (object == nullptr ) [[unlikely]] {
578+ log_debug (LOG_GC, " gc_is_bridge_object was passed a NULL object pointer" );
579+ return FALSE ;
580+ }
562581
563- MonoJavaGCBridgeInfo *bridge_info = get_gc_bridge_info_for_object (object);
564- if (bridge_info == nullptr )
565- return 0 ;
582+ JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (object);
583+ if (control_block == nullptr ) {
584+ return FALSE ;
585+ }
586+
587+ if (control_block->handle == nullptr ) {
588+ log_warn (LOG_GC, " gc_is_bridge_object: control block's handle is NULL" );
589+ return FALSE ;
590+ }
566591
567- mono_field_get_value (object, bridge_info->handle , &handle);
592+ void *handle;
593+ mono_field_get_value (object, reinterpret_cast <MonoClassField*>(control_block->handle ), &handle);
568594 if (handle == nullptr ) {
569595#if DEBUG
570596 MonoClass *mclass = mono_object_get_class (object);
@@ -574,10 +600,10 @@ OSBridge::gc_is_bridge_object (MonoObject *object)
574600 optional_string (mono_class_get_name (mclass))
575601 );
576602#endif
577- return 0 ;
603+ return FALSE ;
578604 }
579605
580- return 1 ;
606+ return TRUE ;
581607}
582608
583609// Add a reference from an IGCUserPeer jobject to another jobject
@@ -604,10 +630,11 @@ mono_bool
604630OSBridge::load_reference_target (OSBridge::AddReferenceTarget target, OSBridge::MonoJavaGCBridgeInfo** bridge_info, jobject *handle)
605631{
606632 if (target.is_mono_object ) {
607- *bridge_info = get_gc_bridge_info_for_object (target.obj );
608- if (!*bridge_info)
633+ JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (target.obj );
634+ if (control_block == nullptr ) {
609635 return FALSE ;
610- mono_field_get_value (target.obj , (*bridge_info)->handle , handle);
636+ }
637+ mono_field_get_value (target.obj , reinterpret_cast <MonoClassField*>(control_block->handle ), handle);
611638 } else {
612639 *handle = target.jobj ;
613640 }
@@ -649,7 +676,11 @@ OSBridge::add_reference (JNIEnv *env, OSBridge::AddReferenceTarget target, OSBri
649676 // Java temporaries do not need this because the entire GCUserPeer is discarded.
650677 if (success && target.is_mono_object ) {
651678 int ref_val = 1 ;
652- mono_field_set_value (target.obj , bridge_info->refs_added , &ref_val);
679+ JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (target.obj );
680+ if (control_block == nullptr ) {
681+ return FALSE ;
682+ }
683+ mono_field_set_value (target.obj , reinterpret_cast <MonoClassField*>(control_block->refs_added ), &ref_val);
653684 }
654685
655686#if DEBUG
@@ -867,14 +898,13 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri
867898 sccs [i]->is_alive = 0 ;
868899
869900 for (j = 0 ; j < sccs [i]->num_objs ; j++) {
870- MonoJavaGCBridgeInfo *bridge_info;
871-
872901 obj = sccs [i]->objs [j];
873902
874- bridge_info = get_gc_bridge_info_for_object (obj);
875- if (bridge_info == nullptr )
903+ JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (obj);
904+ if (control_block == nullptr ) {
876905 continue ;
877- mono_field_get_value (obj, bridge_info->handle , &jref);
906+ }
907+ mono_field_get_value (obj, reinterpret_cast <MonoClassField*>(control_block->handle ), &jref);
878908 if (jref) {
879909 alive++;
880910 if (j > 0 ) {
@@ -884,7 +914,7 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri
884914 );
885915 }
886916 sccs [i]->is_alive = 1 ;
887- mono_field_get_value (obj, bridge_info ->refs_added , &refs_added);
917+ mono_field_get_value (obj, (MonoClassField*) control_block ->refs_added , &refs_added);
888918 if (refs_added) {
889919 jclass java_class = env->GetObjectClass (jref);
890920 clear_method_id = env->GetMethodID (java_class, " monodroidClearReferences" , " ()V" );
@@ -951,13 +981,13 @@ OSBridge::gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xre
951981 for (j = 0 ; j < sccs [i]->num_objs ; ++j) {
952982 MonoObject *obj = sccs [i]->objs [j];
953983
954- MonoJavaGCBridgeInfo *bridge_info = get_gc_bridge_info_for_object (obj);
984+ JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (obj);
955985 jobject handle = 0 ;
956986 void *key_handle = nullptr ;
957- if (bridge_info != nullptr ) {
958- mono_field_get_value (obj, bridge_info ->handle , &handle);
959- if (bridge_info-> key_handle != nullptr ) {
960- mono_field_get_value (obj, bridge_info-> key_handle , &key_handle);
987+ if (control_block != nullptr ) {
988+ mono_field_get_value (obj, reinterpret_cast <MonoClassField*>(control_block ->handle ) , &handle);
989+ if (control_block-> weak_handle != nullptr ) {
990+ mono_field_get_value (obj, reinterpret_cast <MonoClassField*>(control_block-> weak_handle ) , &key_handle);
961991 }
962992 }
963993 MonoClass *klass = mono_object_get_class (obj);
0 commit comments