Skip to content

Commit 577d892

Browse files
committed
bpart: When backdating replace the entire bpart chain
Rather than rewriting the `restriction` of the bparts. With this, I believe this removes that last point where `restriction` is overwritten after construction, hopefully allowing us to go back to the original design where `restriction` is `const` after construction.
1 parent 8c62f42 commit 577d892

File tree

2 files changed

+72
-76
lines changed

2 files changed

+72
-76
lines changed

src/module.c

+72
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,78 @@ JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, ui
248248
return m;
249249
}
250250

251+
// Precondition: world_counter_lock is held
252+
JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val3(
253+
jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *val,
254+
enum jl_partition_kind constant_kind, size_t new_world)
255+
{
256+
JL_GC_PUSH1(&val);
257+
if (!b) {
258+
b = jl_get_module_binding(mod, var, 1);
259+
}
260+
jl_binding_partition_t *new_bpart = NULL;
261+
jl_binding_partition_t *bpart = jl_get_binding_partition(b, new_world);
262+
jl_ptr_kind_union_t pku = jl_atomic_load_relaxed(&bpart->restriction);
263+
while (!new_bpart) {
264+
enum jl_partition_kind kind = decode_restriction_kind(pku);
265+
if (jl_bkind_is_some_constant(kind)) {
266+
if (!val) {
267+
new_bpart = bpart;
268+
break;
269+
}
270+
jl_value_t *old = decode_restriction_value(pku);
271+
JL_GC_PROMISE_ROOTED(old);
272+
if (jl_egal(val, old)) {
273+
new_bpart = bpart;
274+
break;
275+
}
276+
} else if (jl_bkind_is_some_import(kind) && kind != BINDING_KIND_IMPLICIT) {
277+
jl_errorf("cannot declare %s.%s constant; it was already declared as an import",
278+
jl_symbol_name(mod->name), jl_symbol_name(var));
279+
} else if (kind == BINDING_KIND_GLOBAL) {
280+
jl_errorf("cannot declare %s.%s constant; it was already declared global",
281+
jl_symbol_name(mod->name), jl_symbol_name(var));
282+
}
283+
if (bpart->min_world == new_world) {
284+
if (!jl_atomic_cmpswap(&bpart->restriction, &pku, encode_restriction(val, constant_kind))) {
285+
continue;
286+
}
287+
jl_gc_wb(bpart, val);
288+
new_bpart = bpart;
289+
} else {
290+
new_bpart = jl_replace_binding_locked(b, bpart, val, constant_kind, new_world);
291+
}
292+
int need_backdate = new_world && val;
293+
if (need_backdate) {
294+
// We will backdate as long as this partition was never explicitly
295+
// declared const, global, or imported.
296+
jl_binding_partition_t *prev_bpart = bpart;
297+
for (;;) {
298+
jl_ptr_kind_union_t prev_pku = jl_atomic_load_relaxed(&prev_bpart->restriction);
299+
enum jl_partition_kind prev_kind = decode_restriction_kind(prev_pku);
300+
if (jl_bkind_is_some_constant(prev_kind) || prev_kind == BINDING_KIND_GLOBAL ||
301+
(jl_bkind_is_some_import(prev_kind))) {
302+
need_backdate = 0;
303+
break;
304+
}
305+
if (prev_bpart->min_world == 0)
306+
break;
307+
prev_bpart = jl_get_binding_partition(b, prev_bpart->min_world - 1);
308+
}
309+
}
310+
// If backdate is required, create one new binding partition to cover
311+
// the entire backdate range.
312+
if (need_backdate) {
313+
jl_binding_partition_t *backdate_bpart = new_binding_partition();
314+
jl_atomic_store_relaxed(&backdate_bpart->restriction, encode_restriction(val, BINDING_KIND_BACKDATED_CONST));
315+
jl_atomic_store_relaxed(&backdate_bpart->max_world, new_world - 1);
316+
jl_atomic_store_release(&new_bpart->next, backdate_bpart);
317+
}
318+
}
319+
JL_GC_POP();
320+
return new_bpart;
321+
}
322+
251323
JL_DLLEXPORT jl_module_t *jl_new_module(jl_sym_t *name, jl_module_t *parent)
252324
{
253325
return jl_new_module_(name, parent, 1);

src/toplevel.c

-76
Original file line numberDiff line numberDiff line change
@@ -754,82 +754,6 @@ static void jl_eval_errorf(jl_module_t *m, const char *filename, int lineno, con
754754
JL_GC_POP();
755755
}
756756

757-
JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val3(
758-
jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *val,
759-
enum jl_partition_kind constant_kind, size_t new_world)
760-
{
761-
JL_GC_PUSH1(&val);
762-
if (!b) {
763-
b = jl_get_module_binding(mod, var, 1);
764-
}
765-
jl_binding_partition_t *new_bpart = NULL;
766-
jl_binding_partition_t *bpart = jl_get_binding_partition(b, new_world);
767-
jl_ptr_kind_union_t pku = jl_atomic_load_relaxed(&bpart->restriction);
768-
while (!new_bpart) {
769-
enum jl_partition_kind kind = decode_restriction_kind(pku);
770-
if (jl_bkind_is_some_constant(kind)) {
771-
if (!val) {
772-
new_bpart = bpart;
773-
break;
774-
}
775-
jl_value_t *old = decode_restriction_value(pku);
776-
JL_GC_PROMISE_ROOTED(old);
777-
if (jl_egal(val, old)) {
778-
new_bpart = bpart;
779-
break;
780-
}
781-
} else if (jl_bkind_is_some_import(kind) && kind != BINDING_KIND_IMPLICIT) {
782-
jl_errorf("cannot declare %s.%s constant; it was already declared as an import",
783-
jl_symbol_name(mod->name), jl_symbol_name(var));
784-
} else if (kind == BINDING_KIND_GLOBAL) {
785-
jl_errorf("cannot declare %s.%s constant; it was already declared global",
786-
jl_symbol_name(mod->name), jl_symbol_name(var));
787-
}
788-
if (bpart->min_world == new_world) {
789-
if (!jl_atomic_cmpswap(&bpart->restriction, &pku, encode_restriction(val, constant_kind))) {
790-
continue;
791-
}
792-
jl_gc_wb(bpart, val);
793-
new_bpart = bpart;
794-
} else {
795-
new_bpart = jl_replace_binding_locked(b, bpart, val, constant_kind, new_world);
796-
}
797-
int need_backdate = new_world && val;
798-
if (need_backdate) {
799-
// We will backdate as long as this partition was never explicitly
800-
// declared const, global, or imported.
801-
jl_binding_partition_t *prev_bpart = bpart;
802-
for (;;) {
803-
jl_ptr_kind_union_t prev_pku = jl_atomic_load_relaxed(&prev_bpart->restriction);
804-
enum jl_partition_kind prev_kind = decode_restriction_kind(prev_pku);
805-
if (jl_bkind_is_some_constant(prev_kind) || prev_kind == BINDING_KIND_GLOBAL ||
806-
(jl_bkind_is_some_import(prev_kind))) {
807-
need_backdate = 0;
808-
break;
809-
}
810-
if (prev_bpart->min_world == 0)
811-
break;
812-
prev_bpart = jl_get_binding_partition(b, prev_bpart->min_world - 1);
813-
}
814-
}
815-
// If backdate is required, rewrite all previous binding partitions to
816-
// backdated const
817-
if (need_backdate) {
818-
// We will backdate as long as this partition was never explicitly
819-
// declared const, global, or *explicitly* imported.
820-
jl_binding_partition_t *prev_bpart = bpart;
821-
for (;;) {
822-
jl_atomic_store_relaxed(&prev_bpart->restriction, encode_restriction(val, BINDING_KIND_BACKDATED_CONST));
823-
if (prev_bpart->min_world == 0)
824-
break;
825-
prev_bpart = jl_get_binding_partition(b, prev_bpart->min_world - 1);
826-
}
827-
}
828-
}
829-
JL_GC_POP();
830-
return new_bpart;
831-
}
832-
833757
JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val2(
834758
jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *val,
835759
enum jl_partition_kind constant_kind)

0 commit comments

Comments
 (0)