@@ -42,9 +42,6 @@ const uint32_t OSBridge::NUM_GC_BRIDGE_TYPES = NUM_XA_GC_BRIDGE_TYPES + NUM_J
42
42
OSBridge::MonoJavaGCBridgeInfo OSBridge::mono_java_gc_bridge_info [NUM_GC_BRIDGE_TYPES];
43
43
44
44
OSBridge::MonoJavaGCBridgeInfo OSBridge::empty_bridge_info = {
45
- nullptr ,
46
- nullptr ,
47
- nullptr ,
48
45
nullptr ,
49
46
nullptr
50
47
};
@@ -76,9 +73,14 @@ OSBridge::clear_mono_java_gc_bridge_info ()
76
73
for (uint32_t c = 0 ; c < NUM_GC_BRIDGE_TYPES; c++) {
77
74
MonoJavaGCBridgeInfo *info = &mono_java_gc_bridge_info [c];
78
75
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 ;
82
84
}
83
85
}
84
86
@@ -102,6 +104,19 @@ OSBridge::get_gc_bridge_index (MonoClass *klass)
102
104
: -1 ;
103
105
}
104
106
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
+
105
120
OSBridge::MonoJavaGCBridgeInfo *
106
121
OSBridge::get_gc_bridge_info_for_class (MonoClass *klass)
107
122
{
@@ -456,15 +471,15 @@ OSBridge::monodroid_disable_gc_hooks ()
456
471
mono_bool
457
472
OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj)
458
473
{
459
- jobject handle, weak;
460
474
int type = JNIGlobalRefType;
461
475
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 ) {
464
478
return 0 ;
479
+ }
465
480
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);
468
483
if (gref_log) {
469
484
fprintf (gref_log, " *try_take_global obj=%p -> wref=%p handle=%p\n " , obj, weak, handle);
470
485
fflush (gref_log);
@@ -476,8 +491,8 @@ OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj)
476
491
" at [[gc:take_global_ref_jni]]" , 0 );
477
492
} else if (Logger::gc_spew_enabled ()) [[unlikely]] {
478
493
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 ;
481
496
}
482
497
483
498
MonoClass *klass = mono_object_get_class (obj);
@@ -491,8 +506,8 @@ OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj)
491
506
free (message);
492
507
}
493
508
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;
496
511
497
512
_monodroid_weak_gref_delete (weak, get_object_ref_type (env, weak),
498
513
" finalizer" , gettid (), " at [[gc:take_global_ref_jni]]" , 0 );
@@ -504,26 +519,26 @@ OSBridge::take_global_ref_jni (JNIEnv *env, MonoObject *obj)
504
519
mono_bool
505
520
OSBridge::take_weak_global_ref_jni (JNIEnv *env, MonoObject *obj)
506
521
{
507
- jobject handle, weak;
508
522
int type = JNIWeakGlobalRefType;
509
523
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 ) {
512
526
return 0 ;
527
+ }
513
528
514
- mono_field_get_value (obj, bridge_info ->handle , &handle) ;
529
+ jobject handle = control_block ->handle ;
515
530
if (gref_log) {
516
531
fprintf (gref_log, " *take_weak obj=%p; handle=%p\n " , obj, handle);
517
532
fflush (gref_log);
518
533
}
519
534
520
- weak = env->NewWeakGlobalRef (handle);
535
+ jobject weak = env->NewWeakGlobalRef (handle);
521
536
_monodroid_weak_gref_new (handle, get_object_ref_type (env, handle),
522
537
weak, get_object_ref_type (env, weak),
523
538
" finalizer" , gettid (), " at [[gc:take_weak_global_ref_jni]]" , 0 );
524
539
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;
527
542
528
543
_monodroid_gref_log_delete (handle, get_object_ref_type (env, handle),
529
544
" finalizer" , gettid (), " at [[gc:take_weak_global_ref_jni]]" , 0 );
@@ -558,14 +573,22 @@ OSBridge::gc_bridge_class_kind (MonoClass *klass)
558
573
mono_bool
559
574
OSBridge::gc_is_bridge_object (MonoObject *object)
560
575
{
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
+ }
562
580
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
+ }
566
585
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 ) {
569
592
#if DEBUG
570
593
MonoClass *mclass = mono_object_get_class (object);
571
594
log_info (LOG_GC,
@@ -574,10 +597,10 @@ OSBridge::gc_is_bridge_object (MonoObject *object)
574
597
optional_string (mono_class_get_name (mclass))
575
598
);
576
599
#endif
577
- return 0 ;
600
+ return FALSE ;
578
601
}
579
602
580
- return 1 ;
603
+ return TRUE ;
581
604
}
582
605
583
606
// 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
603
626
mono_bool
604
627
OSBridge::load_reference_target (OSBridge::AddReferenceTarget target, OSBridge::MonoJavaGCBridgeInfo** bridge_info, jobject *handle)
605
628
{
629
+ if (handle == nullptr ) [[unlikely]] {
630
+ return FALSE ;
631
+ }
632
+
606
633
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 ) {
609
636
return FALSE ;
610
- mono_field_get_value (target.obj , (*bridge_info)->handle , handle);
637
+ }
638
+
639
+ *handle = control_block->handle ;
611
640
} else {
612
641
*handle = target.jobj ;
613
642
}
@@ -648,8 +677,11 @@ OSBridge::add_reference (JNIEnv *env, OSBridge::AddReferenceTarget target, OSBri
648
677
// Flag MonoObjects so they can be cleared in gc_cleanup_after_java_collection.
649
678
// Java temporaries do not need this because the entire GCUserPeer is discarded.
650
679
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 ;
653
685
}
654
686
655
687
#if DEBUG
@@ -867,15 +899,15 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri
867
899
sccs [i]->is_alive = 0 ;
868
900
869
901
for (j = 0 ; j < sccs [i]->num_objs ; j++) {
870
- MonoJavaGCBridgeInfo *bridge_info;
871
-
872
902
obj = sccs [i]->objs [j];
873
903
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 ) {
876
906
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 ) {
879
911
alive++;
880
912
if (j > 0 ) {
881
913
abort_unless (
@@ -884,8 +916,8 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri
884
916
);
885
917
}
886
918
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 ) {
889
921
jclass java_class = env->GetObjectClass (jref);
890
922
clear_method_id = env->GetMethodID (java_class, " monodroidClearReferences" , " ()V" );
891
923
env->DeleteLocalRef (java_class);
@@ -951,13 +983,13 @@ OSBridge::gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xre
951
983
for (j = 0 ; j < sccs [i]->num_objs ; ++j) {
952
984
MonoObject *obj = sccs [i]->objs [j];
953
985
954
- MonoJavaGCBridgeInfo *bridge_info = get_gc_bridge_info_for_object (obj);
986
+ JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (obj);
955
987
jobject handle = 0 ;
956
988
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 ;
961
993
}
962
994
}
963
995
MonoClass *klass = mono_object_get_class (obj);
0 commit comments