@@ -113,33 +113,55 @@ function invalidate_method_for_globalref!(gr::GlobalRef, method::Method, invalid
113
113
end
114
114
end
115
115
116
- function invalidate_code_for_globalref! (b:: Core.Binding , invalidated_bpart:: Core.BindingPartition , new_bpart:: Union{Core.BindingPartition, Nothing} , new_max_world:: UInt )
116
+ export_affecting_partition_flags (bpart:: Core.BindingPartition ) =
117
+ ((bpart. kind & PARTITION_MASK_KIND) == PARTITION_KIND_GUARD,
118
+ (bpart. kind & PARTITION_FLAG_EXPORTED) != 0 ,
119
+ (bpart. kind & PARTITION_FLAG_DEPRECATED) != 0 )
120
+
121
+ function invalidate_code_for_globalref! (b:: Core.Binding , invalidated_bpart:: Core.BindingPartition , new_bpart:: Core.BindingPartition , new_max_world:: UInt )
117
122
gr = b. globalref
118
- if (b. flags & BINDING_FLAG_ANY_IMPLICIT_EDGES) != 0
119
- foreach_module_mtable (gr. mod, new_max_world) do mt:: Core.MethodTable
120
- for method in MethodList (mt)
121
- invalidate_method_for_globalref! (gr, method, invalidated_bpart, new_max_world)
123
+
124
+ (_, (ib, ibpart)) = Compiler. walk_binding_partition (b, invalidated_bpart, new_max_world)
125
+ (_, (nb, nbpart)) = Compiler. walk_binding_partition (b, new_bpart, new_max_world+ 1 )
126
+
127
+ # abstract_eval_globalref_partition is the maximum amount of information that inference
128
+ # reads from a binding partition. If this information does not change - we do not need to
129
+ # invalidate any code that inference created, because we know that the result will not change.
130
+ need_to_invalidate_code =
131
+ Compiler. abstract_eval_globalref_partition (nothing , ib, ibpart) != =
132
+ Compiler. abstract_eval_globalref_partition (nothing , nb, nbpart)
133
+
134
+ need_to_invalidate_export = export_affecting_partition_flags (invalidated_bpart) != =
135
+ export_affecting_partition_flags (new_bpart)
136
+
137
+ if need_to_invalidate_code
138
+ if (b. flags & BINDING_FLAG_ANY_IMPLICIT_EDGES) != 0
139
+ foreach_module_mtable (gr. mod, new_max_world) do mt:: Core.MethodTable
140
+ for method in MethodList (mt)
141
+ invalidate_method_for_globalref! (gr, method, invalidated_bpart, new_max_world)
142
+ end
143
+ return true
122
144
end
123
- return true
124
145
end
125
- end
126
- if isdefined (b, : backedges)
127
- for edge in b . backedges
128
- if isa ( edge, CodeInstance )
129
- ccall ( :jl_invalidate_code_instance , Cvoid, (Any, UInt), edge, new_max_world )
130
- elseif isa (edge, Core . Binding)
131
- isdefined (edge, :partitions ) || continue
132
- latest_bpart = edge . partitions
133
- latest_bpart . max_world == typemax (UInt ) || continue
134
- is_some_imported ( binding_kind ( latest_bpart)) || continue
135
- partition_restriction (latest_bpart) === b || continue
136
- invalidate_code_for_globalref! (edge, latest_bpart, nothing , new_max_world)
137
- else
138
- invalidate_method_for_globalref! (gr, edge :: Method , invalidated_bpart, new_max_world)
146
+ if isdefined (b, :backedges )
147
+ for edge in b . backedges
148
+ if isa (edge, CodeInstance)
149
+ ccall ( :jl_invalidate_code_instance , Cvoid, (Any, UInt), edge, new_max_world )
150
+ elseif isa ( edge, Core . Binding )
151
+ isdefined (edge, :partitions ) || continue
152
+ latest_bpart = edge . partitions
153
+ latest_bpart. max_world == typemax (UInt) || continue
154
+ is_some_imported ( binding_kind (latest_bpart) ) || continue
155
+ partition_restriction ( latest_bpart) === b || continue
156
+ invalidate_code_for_globalref! (edge, latest_bpart, latest_bpart, new_max_world)
157
+ else
158
+ invalidate_method_for_globalref! (gr, edge :: Method , invalidated_bpart, new_max_world)
159
+ end
139
160
end
140
161
end
141
162
end
142
- if (invalidated_bpart. kind & PARTITION_FLAG_EXPORTED != 0 ) || (new_bpart != = nothing && (new_bpart. kind & PARTITION_FLAG_EXPORTED != 0 ))
163
+
164
+ if need_to_invalidate_code || need_to_invalidate_export
143
165
# This binding was exported - we need to check all modules that `using` us to see if they
144
166
# have a binding that is affected by this change.
145
167
usings_backedges = ccall (:jl_get_module_usings_backedges , Any, (Any,), gr. mod)
@@ -151,8 +173,12 @@ function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core
151
173
latest_bpart = user_binding. partitions
152
174
latest_bpart. max_world == typemax (UInt) || continue
153
175
binding_kind (latest_bpart) in (PARTITION_KIND_IMPLICIT, PARTITION_KIND_FAILED, PARTITION_KIND_GUARD) || continue
154
- @atomic :release latest_bpart. max_world = new_max_world
155
- invalidate_code_for_globalref! (convert (Core. Binding, user_binding), latest_bpart, nothing , new_max_world)
176
+ new_bpart = need_to_invalidate_export ?
177
+ ccall (:jl_maybe_reresolve_implicit , Any, (Any, Any, Csize_t), user_binding, latest_bpart, new_max_world) :
178
+ latest_bpart
179
+ if need_to_invalidate_code || new_bpart != = latest_bpart
180
+ invalidate_code_for_globalref! (convert (Core. Binding, user_binding), latest_bpart, new_bpart, new_max_world)
181
+ end
156
182
end
157
183
end
158
184
end
0 commit comments