Skip to content

Commit 2148a9e

Browse files
committed
Add note about when a value is moved. Fix aotcompile
1 parent 38d5d3a commit 2148a9e

File tree

2 files changed

+42
-16
lines changed

2 files changed

+42
-16
lines changed

src/aotcompile.cpp

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,10 @@ static void jl_ci_cache_lookup(const jl_cgparams_t &cgparams, jl_method_instance
243243
if (*src_out && jl_is_method(def)) {
244244
PTR_PIN(def);
245245
PTR_PIN(codeinst);
246-
*src_out = jl_uncompress_ir(def, codeinst, (jl_array_t*)*src_out);
246+
PTR_PIN(*src_out);
247+
auto temp = jl_uncompress_ir(def, codeinst, (jl_array_t*)*src_out);
248+
PTR_UNPIN(*src_out);
249+
*src_out = temp;
247250
PTR_UNPIN(codeinst);
248251
PTR_UNPIN(def);
249252
}
@@ -255,7 +258,10 @@ static void jl_ci_cache_lookup(const jl_cgparams_t &cgparams, jl_method_instance
255258
else {
256259
*src_out = jl_type_infer(mi, world, 0);
257260
if (*src_out) {
258-
codeinst = jl_get_method_inferred(mi, (*src_out)->rettype, (*src_out)->min_world, (*src_out)->max_world);
261+
auto rettype = (*src_out)->rettype;
262+
PTR_PIN(rettype);
263+
codeinst = jl_get_method_inferred(mi, rettype, (*src_out)->min_world, (*src_out)->max_world);
264+
PTR_UNPIN(rettype);
259265
if ((*src_out)->inferred) {
260266
jl_value_t *null = nullptr;
261267
jl_atomic_cmpswap_relaxed(&codeinst->inferred, &null, jl_nothing);
@@ -326,11 +332,22 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm
326332
// to compile, or an svec(rettype, sig) describing a C-callable alias to create.
327333
jl_value_t *item = jl_array_ptr_ref(methods, i);
328334
if (jl_is_simplevector(item)) {
329-
if (worlds == 1)
330-
jl_compile_extern_c(wrap(&clone), &params, NULL, jl_svecref(item, 0), jl_svecref(item, 1));
335+
if (worlds == 1) {
336+
// warp is not a safepoint, but it is a function defined in LLVM. We cannot persuade GCChecker that item won't be moved.
337+
PTR_PIN(item);
338+
auto el0 = jl_svecref(item, 0);
339+
auto el1 = jl_svecref(item, 1);
340+
PTR_PIN(el0);
341+
PTR_PIN(el1);
342+
jl_compile_extern_c(wrap(&clone), &params, NULL, el0, el1);
343+
PTR_UNPIN(el1);
344+
PTR_UNPIN(el0);
345+
PTR_UNPIN(item);
346+
}
331347
continue;
332348
}
333349
mi = (jl_method_instance_t*)item;
350+
PTR_PIN(mi);
334351
src = NULL;
335352
// if this method is generally visible to the current compilation world,
336353
// and this is either the primary world, or not applicable in the primary world
@@ -342,17 +359,18 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm
342359
if (src && !emitted.count(codeinst)) {
343360
// now add it to our compilation results
344361
JL_GC_PROMISE_ROOTED(codeinst->rettype);
362+
PTR_PIN(codeinst->rettype);
345363
orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(codeinst->def),
346364
params.tsctx, params.imaging,
347365
clone.getModuleUnlocked()->getDataLayout(),
348366
Triple(clone.getModuleUnlocked()->getTargetTriple()));
349-
PTR_PIN(codeinst->rettype);
350367
jl_llvm_functions_t decls = jl_emit_code(result_m, mi, src, codeinst->rettype, params);
351368
PTR_UNPIN(codeinst->rettype);
352369
if (result_m)
353370
emitted[codeinst] = {std::move(result_m), std::move(decls)};
354371
}
355372
}
373+
PTR_UNPIN(mi);
356374
}
357375

358376
// finally, make sure all referenced methods also get compiled or fixed up
@@ -1048,8 +1066,11 @@ void jl_add_optimization_passes_impl(LLVMPassManagerRef PM, int opt_level, int l
10481066
extern "C" JL_DLLEXPORT
10491067
void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, size_t world, char getwrapper, char optimize, const jl_cgparams_t params)
10501068
{
1051-
if (jl_is_method(mi->def.method) && mi->def.method->source == NULL &&
1052-
mi->def.method->generator == NULL) {
1069+
// Extract this as a new var, otherwise GCChecker won't work correctly.
1070+
auto method = mi->def.method;
1071+
PTR_PIN(method);
1072+
if (jl_is_method(method) && method->source == NULL &&
1073+
method->generator == NULL) {
10531074
// not a generic function
10541075
dump->F = NULL;
10551076
return;
@@ -1059,27 +1080,29 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, siz
10591080
jl_value_t *jlrettype = (jl_value_t*)jl_any_type;
10601081
jl_code_info_t *src = NULL;
10611082
JL_GC_PUSH2(&src, &jlrettype);
1062-
if (jl_is_method(mi->def.method) && mi->def.method->source != NULL && jl_ir_flag_inferred((jl_array_t*)mi->def.method->source)) {
1063-
src = (jl_code_info_t*)mi->def.method->source;
1083+
if (jl_is_method(method) && method->source != NULL && jl_ir_flag_inferred((jl_array_t*)method->source)) {
1084+
src = (jl_code_info_t*)method->source;
10641085
if (src && !jl_is_code_info(src))
1065-
src = jl_uncompress_ir(mi->def.method, NULL, (jl_array_t*)src);
1086+
src = jl_uncompress_ir(method, NULL, (jl_array_t*)src);
10661087
} else {
10671088
jl_value_t *ci = jl_rettype_inferred(mi, world, world);
10681089
if (ci != jl_nothing) {
10691090
jl_code_instance_t *codeinst = (jl_code_instance_t*)ci;
1091+
PTR_PIN(codeinst);
10701092
src = (jl_code_info_t*)jl_atomic_load_relaxed(&codeinst->inferred);
1071-
if ((jl_value_t*)src != jl_nothing && !jl_is_code_info(src) && jl_is_method(mi->def.method))
1072-
src = jl_uncompress_ir(mi->def.method, codeinst, (jl_array_t*)src);
1093+
if ((jl_value_t*)src != jl_nothing && !jl_is_code_info(src) && jl_is_method(method))
1094+
src = jl_uncompress_ir(method, codeinst, (jl_array_t*)src);
10731095
jlrettype = codeinst->rettype;
1096+
PTR_UNPIN(codeinst);
10741097
}
10751098
if (!src || (jl_value_t*)src == jl_nothing) {
10761099
src = jl_type_infer(mi, world, 0);
10771100
if (src)
10781101
jlrettype = src->rettype;
1079-
else if (jl_is_method(mi->def.method)) {
1080-
src = mi->def.method->generator ? jl_code_for_staged(mi) : (jl_code_info_t*)mi->def.method->source;
1081-
if (src && !jl_is_code_info(src) && jl_is_method(mi->def.method))
1082-
src = jl_uncompress_ir(mi->def.method, NULL, (jl_array_t*)src);
1102+
else if (jl_is_method(method)) {
1103+
src = method->generator ? jl_code_for_staged(mi) : (jl_code_info_t*)method->source;
1104+
if (src && !jl_is_code_info(src) && jl_is_method(method))
1105+
src = jl_uncompress_ir(method, NULL, (jl_array_t*)src);
10831106
}
10841107
// TODO: use mi->uninferred
10851108
}
@@ -1131,6 +1154,7 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, siz
11311154
fname = &decls.functionObject;
11321155
F = cast<Function>(m.getModuleUnlocked()->getNamedValue(*fname));
11331156
}
1157+
PTR_UNPIN(method);
11341158
JL_GC_POP();
11351159
if (measure_compile_time_enabled) {
11361160
auto end = jl_hrtime();

src/clangsa/GCChecker.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,8 @@ PDP GCChecker::GCValueBugVisitor::VisitNode(const ExplodedNode *N,
737737
return MakePDP(Pos, "Root was released here.");
738738
} else if (NewValueState->RootDepth != OldValueState->RootDepth) {
739739
return MakePDP(Pos, "Rooting Depth changed here.");
740+
} else if (NewValueState->isMoved() && !OldValueState->isMoved()) {
741+
return MakePDP(Pos, "Value was moved here.");
740742
}
741743
return nullptr;
742744
}

0 commit comments

Comments
 (0)