@@ -13,10 +13,51 @@ extern "C" {
1313#endif
1414
1515// In this translation unit and this translation unit only emit this symbol `extern` for use by julia
16- EXTERN_INLINE_DEFINE jl_binding_partition_t * jl_get_binding_partition (jl_binding_t * b , size_t world ) JL_NOTSAFEPOINT ;
1716EXTERN_INLINE_DEFINE uint8_t jl_bpart_get_kind (jl_binding_partition_t * bpart ) JL_NOTSAFEPOINT ;
1817extern inline enum jl_partition_kind decode_restriction_kind (jl_ptr_kind_union_t pku ) JL_NOTSAFEPOINT ;
1918
19+ static jl_binding_partition_t * new_binding_partition (void )
20+ {
21+ jl_binding_partition_t * bpart = (jl_binding_partition_t * )jl_gc_alloc (jl_current_task -> ptls , sizeof (jl_binding_partition_t ), jl_binding_partition_type );
22+ jl_atomic_store_relaxed (& bpart -> restriction , encode_restriction (NULL , BINDING_KIND_GUARD ));
23+ bpart -> min_world = 0 ;
24+ jl_atomic_store_relaxed (& bpart -> max_world , (size_t )-1 );
25+ jl_atomic_store_relaxed (& bpart -> next , NULL );
26+ #ifdef _P64
27+ bpart -> reserved = 0 ;
28+ #endif
29+ return bpart ;
30+ }
31+
32+ jl_binding_partition_t * jl_get_binding_partition (jl_binding_t * b , size_t world ) {
33+ if (!b )
34+ return NULL ;
35+ assert (jl_is_binding (b ));
36+ jl_value_t * parent = (jl_value_t * )b ;
37+ _Atomic(jl_binding_partition_t * )* insert = & b -> partitions ;
38+ jl_binding_partition_t * bpart = jl_atomic_load_relaxed (insert );
39+ size_t max_world = (size_t )-1 ;
40+ while (1 ) {
41+ while (bpart && world < bpart -> min_world ) {
42+ insert = & bpart -> next ;
43+ max_world = bpart -> min_world - 1 ;
44+ parent = (jl_value_t * )bpart ;
45+ bpart = jl_atomic_load_relaxed (& bpart -> next );
46+ }
47+ if (bpart && world <= jl_atomic_load_relaxed (& bpart -> max_world ))
48+ return bpart ;
49+ jl_binding_partition_t * new_bpart = new_binding_partition ();
50+ jl_atomic_store_relaxed (& new_bpart -> next , bpart );
51+ if (bpart )
52+ new_bpart -> min_world = jl_atomic_load_relaxed (& bpart -> max_world ) + 1 ;
53+ jl_atomic_store_relaxed (& new_bpart -> max_world , max_world );
54+ if (jl_atomic_cmpswap (insert , & bpart , new_bpart )) {
55+ jl_gc_wb (parent , new_bpart );
56+ return new_bpart ;
57+ }
58+ }
59+ }
60+
2061JL_DLLEXPORT jl_binding_partition_t * jl_get_globalref_partition (jl_globalref_t * gr , size_t world )
2162{
2263 if (!gr )
@@ -188,19 +229,6 @@ static jl_globalref_t *jl_new_globalref(jl_module_t *mod, jl_sym_t *name, jl_bin
188229 return g ;
189230}
190231
191- static jl_binding_partition_t * new_binding_partition (void )
192- {
193- jl_binding_partition_t * bpart = (jl_binding_partition_t * )jl_gc_alloc (jl_current_task -> ptls , sizeof (jl_binding_partition_t ), jl_binding_partition_type );
194- jl_atomic_store_relaxed (& bpart -> restriction , encode_restriction (NULL , BINDING_KIND_GUARD ));
195- bpart -> min_world = 0 ;
196- jl_atomic_store_relaxed (& bpart -> max_world , (size_t )-1 );
197- jl_atomic_store_relaxed (& bpart -> next , NULL );
198- #ifdef _P64
199- bpart -> reserved = 0 ;
200- #endif
201- return bpart ;
202- }
203-
204232static jl_binding_t * new_binding (jl_module_t * mod , jl_sym_t * name )
205233{
206234 jl_task_t * ct = jl_current_task ;
@@ -215,9 +243,7 @@ static jl_binding_t *new_binding(jl_module_t *mod, jl_sym_t *name)
215243 JL_GC_PUSH1 (& b );
216244 b -> globalref = jl_new_globalref (mod , name , b );
217245 jl_gc_wb (b , b -> globalref );
218- jl_binding_partition_t * bpart = new_binding_partition ();
219- jl_atomic_store_relaxed (& b -> partitions , bpart );
220- jl_gc_wb (b , bpart );
246+ jl_atomic_store_relaxed (& b -> partitions , NULL );
221247 JL_GC_POP ();
222248 return b ;
223249}
@@ -324,6 +350,12 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_const(jl_binding_t *b)
324350 return decode_restriction_value (pku );
325351}
326352
353+ JL_DLLEXPORT jl_value_t * jl_bpart_get_restriction_value (jl_binding_partition_t * bpart )
354+ {
355+ jl_ptr_kind_union_t pku = jl_atomic_load_relaxed (& bpart -> restriction );
356+ return decode_restriction_value (pku );
357+ }
358+
327359typedef struct _modstack_t {
328360 jl_module_t * m ;
329361 jl_sym_t * var ;
@@ -952,6 +984,28 @@ JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var
952984 jl_gc_wb (bpart , val );
953985}
954986
987+ extern jl_mutex_t world_counter_lock ;
988+ JL_DLLEXPORT void jl_disable_binding (jl_globalref_t * gr )
989+ {
990+ jl_binding_t * b = gr -> binding ;
991+ b = jl_resolve_owner (b , gr -> mod , gr -> name , NULL );
992+ jl_binding_partition_t * bpart = jl_get_binding_partition (b , jl_current_task -> world_age );
993+
994+ if (decode_restriction_kind (jl_atomic_load_relaxed (& bpart -> restriction )) == BINDING_KIND_GUARD ) {
995+ // Already guard
996+ return ;
997+ }
998+
999+ JL_LOCK (& world_counter_lock );
1000+ jl_task_t * ct = jl_current_task ;
1001+ size_t new_max_world = jl_atomic_load_acquire (& jl_world_counter );
1002+ // TODO: Trigger invalidation here
1003+ (void )ct ;
1004+ jl_atomic_store_release (& bpart -> max_world , new_max_world );
1005+ jl_atomic_store_release (& jl_world_counter , new_max_world + 1 );
1006+ JL_UNLOCK (& world_counter_lock );
1007+ }
1008+
9551009JL_DLLEXPORT int jl_globalref_is_const (jl_globalref_t * gr )
9561010{
9571011 jl_binding_t * b = gr -> binding ;
@@ -1023,13 +1077,17 @@ void jl_binding_deprecation_warning(jl_module_t *m, jl_sym_t *s, jl_binding_t *b
10231077
10241078jl_value_t * jl_check_binding_wr (jl_binding_t * b JL_PROPAGATES_ROOT , jl_module_t * mod , jl_sym_t * var , jl_value_t * rhs JL_MAYBE_UNROOTED , int reassign )
10251079{
1080+ JL_GC_PUSH1 (& rhs ); // callee-rooted
10261081 jl_binding_partition_t * bpart = jl_get_binding_partition (b , jl_current_task -> world_age );
10271082 jl_ptr_kind_union_t pku = jl_atomic_load_relaxed (& bpart -> restriction );
10281083 assert (!jl_bkind_is_some_guard (decode_restriction_kind (pku )) && !jl_bkind_is_some_import (decode_restriction_kind (pku )));
10291084 if (jl_bkind_is_some_constant (decode_restriction_kind (pku ))) {
10301085 jl_value_t * old = decode_restriction_value (pku );
1031- if (jl_egal (rhs , old ))
1086+ JL_GC_PROMISE_ROOTED (old );
1087+ if (jl_egal (rhs , old )) {
1088+ JL_GC_POP ();
10321089 return NULL ;
1090+ }
10331091 if (jl_typeof (rhs ) == jl_typeof (old ))
10341092 jl_errorf ("invalid redefinition of constant %s.%s. This redefinition may be permitted using the `const` keyword." ,
10351093 jl_symbol_name (mod -> name ), jl_symbol_name (var ));
@@ -1038,13 +1096,13 @@ jl_value_t *jl_check_binding_wr(jl_binding_t *b JL_PROPAGATES_ROOT, jl_module_t
10381096 jl_symbol_name (mod -> name ), jl_symbol_name (var ));
10391097 }
10401098 jl_value_t * old_ty = decode_restriction_value (pku );
1099+ JL_GC_PROMISE_ROOTED (old_ty );
10411100 if (old_ty != (jl_value_t * )jl_any_type && jl_typeof (rhs ) != old_ty ) {
1042- JL_GC_PUSH1 (& rhs ); // callee-rooted
10431101 if (!jl_isa (rhs , old_ty ))
10441102 jl_errorf ("cannot assign an incompatible value to the global %s.%s." ,
10451103 jl_symbol_name (mod -> name ), jl_symbol_name (var ));
1046- JL_GC_POP ();
10471104 }
1105+ JL_GC_POP ();
10481106 return old_ty ;
10491107}
10501108
@@ -1081,6 +1139,7 @@ JL_DLLEXPORT jl_value_t *jl_checked_modify(jl_binding_t *b, jl_module_t *mod, jl
10811139 jl_errorf ("invalid redefinition of constant %s.%s" ,
10821140 jl_symbol_name (mod -> name ), jl_symbol_name (var ));
10831141 jl_value_t * ty = decode_restriction_value (pku );
1142+ JL_GC_PROMISE_ROOTED (ty );
10841143 return modify_value (ty , & b -> value , (jl_value_t * )b , op , rhs , 1 , mod , var );
10851144}
10861145
0 commit comments