Skip to content

Commit 3778b80

Browse files
vtjnashKristofferC
authored andcommitted
add missing wb in jl_maybe_reresolve_implicit (#57804)
Also stop using a custom rooting strategy that is not understandable by the static analysis. Unfortunately, we currently have no checker for missing jl_gc_wb calls however. Fix #57700 (cherry picked from commit abb1313)
1 parent 65b5aa7 commit 3778b80

File tree

2 files changed

+17
-14
lines changed

2 files changed

+17
-14
lines changed

src/julia_internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -855,8 +855,7 @@ typedef struct _modstack_t {
855855
jl_binding_t *b;
856856
struct _modstack_t *prev;
857857
} modstack_t;
858-
void jl_check_new_binding_implicit(
859-
jl_binding_partition_t *new_bpart JL_MAYBE_UNROOTED, jl_binding_t *b, modstack_t *st, size_t world);
858+
void jl_check_new_binding_implicit(jl_binding_partition_t *new_bpart, jl_binding_t *b, modstack_t *st, size_t world);
860859

861860
#ifndef __clang_gcanalyzer__
862861
// The analyzer doesn't like looking through the arraylist, so just model the

src/module.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static int eq_bindings(jl_binding_partition_t *owner, jl_binding_t *alias, size_
4747

4848
// find a binding from a module's `usings` list
4949
void jl_check_new_binding_implicit(
50-
jl_binding_partition_t *new_bpart JL_MAYBE_UNROOTED, jl_binding_t *b, modstack_t *st, size_t world)
50+
jl_binding_partition_t *new_bpart, jl_binding_t *b, modstack_t *st, size_t world)
5151
{
5252
modstack_t top = { b, st };
5353
modstack_t *tmp = st;
@@ -59,7 +59,6 @@ void jl_check_new_binding_implicit(
5959
}
6060
}
6161

62-
JL_GC_PUSH1(&new_bpart);
6362
jl_module_t *m = b->globalref->mod;
6463
jl_sym_t *var = b->globalref->name;
6564

@@ -164,31 +163,33 @@ void jl_check_new_binding_implicit(
164163
new_bpart->kind = guard_kind;
165164
new_bpart->restriction = NULL;
166165
}
167-
JL_GC_POP();
168-
return;
169166
}
170167

171168
JL_DLLEXPORT jl_binding_partition_t *jl_maybe_reresolve_implicit(jl_binding_t *b, size_t new_max_world)
172169
{
173170
jl_binding_partition_t *new_bpart = new_binding_partition();
174171
jl_binding_partition_t *bpart = jl_atomic_load_acquire(&b->partitions);
175172
assert(bpart);
173+
JL_GC_PUSH1(&new_bpart);
176174
while (1) {
177175
jl_atomic_store_relaxed(&new_bpart->next, bpart);
178176
jl_gc_wb(new_bpart, bpart);
179177
jl_check_new_binding_implicit(new_bpart, b, NULL, new_max_world+1);
180-
JL_GC_PROMISE_ROOTED(new_bpart); // TODO: Analyzer doesn't understand MAYBE_UNROOTED properly
181178
if (bpart->kind & PARTITION_FLAG_EXPORTED)
182179
new_bpart->kind |= PARTITION_FLAG_EXPORTED;
183-
if (new_bpart->kind == bpart->kind && new_bpart->restriction == bpart->restriction)
180+
if (new_bpart->kind == bpart->kind && new_bpart->restriction == bpart->restriction) {
181+
JL_GC_POP();
184182
return bpart;
183+
}
185184
// Resolution changed, insert the new partition
186185
size_t expected_max_world = ~(size_t)0;
187186
if (jl_atomic_cmpswap(&bpart->max_world, &expected_max_world, new_max_world) &&
188-
jl_atomic_cmpswap(&b->partitions, &bpart, new_bpart))
189-
break;
187+
jl_atomic_cmpswap(&b->partitions, &bpart, new_bpart)) {
188+
jl_gc_wb(b, new_bpart);
189+
JL_GC_POP();
190+
return new_bpart;
191+
}
190192
}
191-
return new_bpart;
192193
}
193194

194195
STATIC_INLINE jl_binding_partition_t *jl_get_binding_partition_(jl_binding_t *b JL_PROPAGATES_ROOT, jl_value_t *parent, _Atomic(jl_binding_partition_t *)*insert, size_t world, modstack_t *st) JL_GLOBALLY_ROOTED
@@ -197,28 +198,31 @@ STATIC_INLINE jl_binding_partition_t *jl_get_binding_partition_(jl_binding_t *b
197198
jl_binding_partition_t *bpart = jl_atomic_load_relaxed(insert);
198199
size_t max_world = (size_t)-1;
199200
jl_binding_partition_t *new_bpart = NULL;
201+
JL_GC_PUSH1(&new_bpart);
200202
while (1) {
201203
while (bpart && world < bpart->min_world) {
202204
insert = &bpart->next;
203205
max_world = bpart->min_world - 1;
204206
parent = (jl_value_t *)bpart;
205207
bpart = jl_atomic_load_relaxed(&bpart->next);
206208
}
207-
if (bpart && world <= jl_atomic_load_relaxed(&bpart->max_world))
209+
if (bpart && world <= jl_atomic_load_relaxed(&bpart->max_world)) {
210+
JL_GC_POP();
208211
return bpart;
212+
}
209213
if (!new_bpart)
210214
new_bpart = new_binding_partition();
211215
jl_atomic_store_relaxed(&new_bpart->next, bpart);
212216
if (bpart)
213217
jl_gc_wb(new_bpart, bpart); // Not fresh the second time around the loop
214218
new_bpart->min_world = bpart ? jl_atomic_load_relaxed(&bpart->max_world) + 1 : 0;
215219
jl_atomic_store_relaxed(&new_bpart->max_world, max_world);
216-
JL_GC_PROMISE_ROOTED(new_bpart); // TODO: Analyzer doesn't understand MAYBE_UNROOTED properly
217220
jl_check_new_binding_implicit(new_bpart, b, st, world);
218221
if (bpart && (bpart->kind & PARTITION_FLAG_EXPORTED))
219222
new_bpart->kind |= PARTITION_FLAG_EXPORTED;
220223
if (jl_atomic_cmpswap(insert, &bpart, new_bpart)) {
221224
jl_gc_wb(parent, new_bpart);
225+
JL_GC_POP();
222226
return new_bpart;
223227
}
224228
}
@@ -1435,7 +1439,7 @@ JL_DLLEXPORT jl_binding_partition_t *jl_replace_binding_locked2(jl_binding_t *b,
14351439
new_bpart->min_world = new_world;
14361440
if ((kind & PARTITION_MASK_KIND) == PARTITION_KIND_IMPLICIT_RECOMPUTE) {
14371441
assert(!restriction_val);
1438-
jl_check_new_binding_implicit(new_bpart /* callee rooted */, b, NULL, new_world);
1442+
jl_check_new_binding_implicit(new_bpart, b, NULL, new_world);
14391443
new_bpart->kind |= kind & PARTITION_MASK_FLAG;
14401444
if (new_bpart->kind == old_bpart->kind && new_bpart->restriction == old_bpart->restriction) {
14411445
JL_GC_POP();

0 commit comments

Comments
 (0)