@@ -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 " , obj, weak, handle);
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 " , obj, handle);
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