@@ -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,14 @@ 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->weak_handle  = nullptr ;
83+ 		control_block->refs_added  = 0 ;
8284	}
8385}
8486
@@ -102,6 +104,19 @@ OSBridge::get_gc_bridge_index (MonoClass *klass)
102104		: -1 ;
103105}
104106
107+ OSBridge::JniObjectReferenceControlBlock*
108+ OSBridge::get_gc_control_block_for_object  (MonoObject *obj)
109+ {
110+ 	MonoJavaGCBridgeInfo *bridge_info = get_gc_bridge_info_for_object  (obj);
111+ 	if  (bridge_info == nullptr ) {
112+ 		return  nullptr ;
113+ 	}
114+ 
115+ 	JniObjectReferenceControlBlock *control_block = nullptr ;
116+ 	mono_field_get_value  (obj, bridge_info->jniObjectReferenceControlBlock , &control_block);
117+ 	return  control_block;
118+ }
119+ 
105120OSBridge::MonoJavaGCBridgeInfo *
106121OSBridge::get_gc_bridge_info_for_class  (MonoClass *klass)
107122{
@@ -456,15 +471,15 @@ OSBridge::monodroid_disable_gc_hooks ()
456471mono_bool
457472OSBridge::take_global_ref_jni  (JNIEnv *env, MonoObject *obj)
458473{
459- 	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) ;
467- 	handle = env->NewGlobalRef  (weak);
481+ 	jobject weak = control_block ->handle ;
482+ 	jobject  handle = env->NewGlobalRef  (weak);
468483	if  (gref_log) {
469484		fprintf  (gref_log, " *try_take_global obj=%p -> wref=%p handle=%p\n " 
470485		fflush  (gref_log);
@@ -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  !=  nullptr ) {
495+ 			key_handle = control_block-> weak_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+ 	control_block ->handle  =  handle;
510+ 	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 );
@@ -504,26 +519,26 @@ OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj)
504519mono_bool
505520OSBridge::take_weak_global_ref_jni  (JNIEnv *env, MonoObject *obj)
506521{
507- 	jobject handle, weak;
508522	int  type = JNIWeakGlobalRefType;
509523
510- 	MonoJavaGCBridgeInfo    *bridge_info    =  get_gc_bridge_info_for_object  (obj);
511- 	if  (bridge_info  == nullptr )
524+ 	JniObjectReferenceControlBlock *control_block =  get_gc_control_block_for_object  (obj);
525+ 	if  (control_block  == nullptr ) { 
512526		return  0 ;
527+ 	}
513528
514- 	mono_field_get_value  (obj, bridge_info ->handle , &handle) ;
529+ 	jobject handle = control_block ->handle ;
515530	if  (gref_log) {
516531		fprintf  (gref_log, " *take_weak obj=%p; handle=%p\n " 
517532		fflush  (gref_log);
518533	}
519534
520- 	weak = env->NewWeakGlobalRef  (handle);
535+ 	jobject  weak = env->NewWeakGlobalRef  (handle);
521536	_monodroid_weak_gref_new  (handle, get_object_ref_type  (env, handle),
522537			weak, get_object_ref_type  (env, weak),
523538			" finalizer" gettid  (), "    at [[gc:take_weak_global_ref_jni]]" 0 );
524539
525- 	mono_field_set_value  (obj, bridge_info ->handle , & weak) ;
526- 	mono_field_set_value  (obj, bridge_info ->handle_type , & type) ;
540+ 	control_block ->handle  =  weak;
541+ 	control_block ->handle_type  =  type;
527542
528543	_monodroid_gref_log_delete  (handle, get_object_ref_type  (env, handle),
529544			" finalizer" gettid  (), "    at [[gc:take_weak_global_ref_jni]]" 0 );
@@ -558,14 +573,22 @@ OSBridge::gc_bridge_class_kind (MonoClass *klass)
558573mono_bool
559574OSBridge::gc_is_bridge_object  (MonoObject *object)
560575{
561- 	void  *handle;
576+ 	if  (object == nullptr ) [[unlikely]] {
577+ 		log_debug  (LOG_GC, " gc_is_bridge_object was passed a NULL object pointer" 
578+ 		return  FALSE ;
579+ 	}
562580
563- 	MonoJavaGCBridgeInfo    *bridge_info    = get_gc_bridge_info_for_object  (object);
564- 	if  (bridge_info == nullptr )
565- 		return  0 ;
581+ 	JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object  (object);
582+ 	if  (control_block == nullptr ) {
583+ 		return  FALSE ;
584+ 	}
566585
567- 	mono_field_get_value  (object, bridge_info->handle , &handle);
568- 	if  (handle == nullptr ) {
586+ 	if  (control_block->handle  == nullptr ) {
587+ 		log_warn  (LOG_GC, " gc_is_bridge_object: control block's handle is NULL" 
588+ 		return  FALSE ;
589+ 	}
590+ 
591+ 	if  (control_block->handle  == nullptr ) {
569592#if  DEBUG
570593		MonoClass *mclass = mono_object_get_class  (object);
571594		log_info  (LOG_GC,
@@ -574,10 +597,10 @@ OSBridge::gc_is_bridge_object (MonoObject *object)
574597			optional_string  (mono_class_get_name  (mclass))
575598		);
576599#endif 
577- 		return  0 ;
600+ 		return  FALSE ;
578601	}
579602
580- 	return  1 ;
603+ 	return  TRUE ;
581604}
582605
583606//  Add a reference from an IGCUserPeer jobject to another jobject
@@ -603,11 +626,17 @@ OSBridge::add_reference_jobject (JNIEnv *env, jobject handle, jobject reffed_han
603626mono_bool
604627OSBridge::load_reference_target  (OSBridge::AddReferenceTarget target, OSBridge::MonoJavaGCBridgeInfo** bridge_info, jobject *handle)
605628{
629+ 	if  (handle == nullptr ) [[unlikely]] {
630+ 		return  FALSE ;
631+ 	}
632+ 
606633	if  (target.is_mono_object ) {
607- 		*bridge_info  = get_gc_bridge_info_for_object  (target.obj );
608- 		if  (!*bridge_info) 
634+ 		JniObjectReferenceControlBlock *control_block  = get_gc_control_block_for_object  (target.obj );
635+ 		if  (control_block ==  nullptr ) { 
609636			return  FALSE ;
610- 		mono_field_get_value  (target.obj , (*bridge_info)->handle , handle);
637+ 		}
638+ 
639+ 		*handle = control_block->handle ;
611640	} else  {
612641		*handle = target.jobj ;
613642	}
@@ -648,8 +677,11 @@ OSBridge::add_reference (JNIEnv *env, OSBridge::AddReferenceTarget target, OSBri
648677	//  Flag MonoObjects so they can be cleared in gc_cleanup_after_java_collection.
649678	//  Java temporaries do not need this because the entire GCUserPeer is discarded.
650679	if  (success && target.is_mono_object ) {
651- 		int  ref_val = 1 ;
652- 		mono_field_set_value  (target.obj , bridge_info->refs_added , &ref_val);
680+ 		JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object  (target.obj );
681+ 		if  (control_block == nullptr ) {
682+ 			return  FALSE ;
683+ 		}
684+ 		control_block->refs_added  = 1 ;
653685	}
654686
655687#if  DEBUG
@@ -867,15 +899,15 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri
867899		sccs [i]->is_alive  = 0 ;
868900
869901		for  (j = 0 ; j < sccs [i]->num_objs ; j++) {
870- 			MonoJavaGCBridgeInfo    *bridge_info;
871- 
872902			obj = sccs [i]->objs  [j];
873903
874- 			bridge_info =  get_gc_bridge_info_for_object  (obj);
875- 			if  (bridge_info  == nullptr )
904+ 			JniObjectReferenceControlBlock *control_block =  get_gc_control_block_for_object  (obj);
905+ 			if  (control_block  == nullptr ) { 
876906				continue ;
877- 			mono_field_get_value  (obj, bridge_info->handle , &jref);
878- 			if  (jref) {
907+ 			}
908+ 
909+ 			jref = control_block->handle ;
910+ 			if  (jref != nullptr ) {
879911				alive++;
880912				if  (j > 0 ) {
881913					abort_unless  (
@@ -884,8 +916,8 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri
884916					);
885917				}
886918				sccs [i]->is_alive  = 1 ;
887- 				mono_field_get_value  (obj, bridge_info ->refs_added , &refs_added) ;
888- 				if  (refs_added) {
919+ 				refs_added = control_block ->refs_added ;
920+ 				if  (refs_added !=  0 ) {
889921					jclass java_class = env->GetObjectClass  (jref);
890922					clear_method_id = env->GetMethodID  (java_class, " monodroidClearReferences" " ()V" 
891923					env->DeleteLocalRef  (java_class);
@@ -951,13 +983,13 @@ OSBridge::gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xre
951983			for  (j = 0 ; j < sccs [i]->num_objs ; ++j) {
952984				MonoObject *obj = sccs [i]->objs  [j];
953985
954- 				MonoJavaGCBridgeInfo    *bridge_info    =  get_gc_bridge_info_for_object  (obj);
986+ 				JniObjectReferenceControlBlock *control_block =  get_gc_control_block_for_object  (obj);
955987				jobject handle      = 0 ;
956988				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) ;
989+ 				if  (control_block  != nullptr ) {
990+ 					handle = control_block ->handle ;
991+ 					if  (control_block-> weak_handle  != nullptr ) {
992+ 						key_handle = control_block-> weak_handle ;
961993					}
962994				}
963995				MonoClass *klass = mono_object_get_class  (obj);
0 commit comments