Skip to content

Commit 1a1a9a6

Browse files
authored
Merge pull request #17081 from JuliaLang/yyc/gc/finalize-ptr
Optimize finalizers
2 parents 6ddf9bc + 23a8f42 commit 1a1a9a6

17 files changed

+378
-204
lines changed

base/base.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,16 @@ function finalizer(o::ANY, f::ANY)
7070
if isimmutable(o)
7171
error("objects of type ", typeof(o), " cannot be finalized")
7272
end
73-
ccall(:jl_gc_add_finalizer, Void, (Any,Any), o, f)
73+
ccall(:jl_gc_add_finalizer_th, Void, (Ptr{Void}, Any, Any),
74+
Core.getptls(), o, f)
75+
end
76+
function finalizer{T}(o::T, f::Ptr{Void})
77+
@_inline_meta
78+
if isimmutable(T)
79+
error("objects of type ", T, " cannot be finalized")
80+
end
81+
ccall(:jl_gc_add_ptr_finalizer, Void, (Ptr{Void}, Any, Ptr{Void}),
82+
Core.getptls(), o, f)
7483
end
7584

7685
finalize(o::ANY) = ccall(:jl_finalize, Void, (Any,), o)

base/boot.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ immutable String <: AbstractString
225225
String(d::Array{UInt8,1}) = new(d)
226226
end
227227

228+
# This should always be inlined
229+
getptls() = ccall(:jl_get_ptls_states, Ptr{Void}, ())
230+
228231
include(fname::String) = ccall(:jl_load_, Any, (Any,), fname)
229232

230233
eval(e::ANY) = eval(Main, e)

src/ccall.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,17 @@ static jl_cgval_t emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
12351235
emit_signal_fence();
12361236
return ghostValue(jl_void_type);
12371237
}
1238+
if (fptr == (void(*)(void))&jl_get_ptls_states ||
1239+
((!f_lib || (intptr_t)f_lib == 2) && f_name &&
1240+
strcmp(f_name, "jl_get_ptls_states") == 0)) {
1241+
assert(lrt == T_pint8);
1242+
assert(!isVa);
1243+
assert(nargt == 0);
1244+
JL_GC_POP();
1245+
return mark_or_box_ccall_result(
1246+
builder.CreateBitCast(ctx->ptlsStates, lrt),
1247+
retboxed, args[2], rt, static_rt, ctx);
1248+
}
12381249
if (fptr == &jl_sigatomic_begin ||
12391250
((!f_lib || (intptr_t)f_lib == 2) && f_name &&
12401251
strcmp(f_name, "jl_sigatomic_begin") == 0)) {

src/codegen.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,7 @@ static uint64_t compute_obj_symsize(const object::ObjectFile *obj, uint64_t offs
13181318
extern "C" JL_DLLEXPORT
13191319
const jl_value_t *jl_dump_function_asm(void *f, int raw_mc)
13201320
{
1321+
jl_tls_states_t *ptls = jl_get_ptls_states();
13211322
std::string code;
13221323
llvm::raw_string_ostream stream(code);
13231324
#ifndef LLVM37
@@ -1362,7 +1363,7 @@ const jl_value_t *jl_dump_function_asm(void *f, int raw_mc)
13621363
return (jl_value_t*)jl_pchar_to_array((char*)fptr, symsize);
13631364
}
13641365

1365-
int8_t gc_state = jl_gc_safe_enter();
1366+
int8_t gc_state = jl_gc_safe_enter(ptls);
13661367
jl_dump_asm_internal(fptr, symsize, slide,
13671368
#ifndef USE_MCJIT
13681369
context,
@@ -1378,7 +1379,7 @@ const jl_value_t *jl_dump_function_asm(void *f, int raw_mc)
13781379
#ifndef LLVM37
13791380
fstream.flush();
13801381
#endif
1381-
jl_gc_safe_leave(gc_state);
1382+
jl_gc_safe_leave(ptls, gc_state);
13821383

13831384
return jl_cstr_to_string(const_cast<char*>(stream.str().c_str()));
13841385
}

src/debuginfo.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,10 @@ class JuliaJITEventListener: public JITEventListener
251251
virtual void NotifyFunctionEmitted(const Function &F, void *Code,
252252
size_t Size, const EmittedFunctionDetails &Details)
253253
{
254+
jl_tls_states_t *ptls = jl_get_ptls_states();
254255
// This function modify linfo->fptr in GC safe region.
255256
// This should be fine since the GC won't scan this field.
256-
int8_t gc_state = jl_gc_safe_enter();
257+
int8_t gc_state = jl_gc_safe_enter(ptls);
257258
uv_rwlock_wrlock(&threadsafe);
258259
StringRef sName = F.getName();
259260
StringMap<jl_lambda_info_t*>::iterator linfo_it = linfo_in_flight.find(sName);
@@ -274,7 +275,7 @@ class JuliaJITEventListener: public JITEventListener
274275
const_cast<Function*>(&F)->deleteBody();
275276
#endif
276277
uv_rwlock_wrunlock(&threadsafe);
277-
jl_gc_safe_leave(gc_state);
278+
jl_gc_safe_leave(ptls, gc_state);
278279
}
279280

280281
std::map<size_t, FuncInfo, revcomp>& getMap()
@@ -309,9 +310,10 @@ class JuliaJITEventListener: public JITEventListener
309310
virtual void NotifyObjectEmitted(const ObjectImage &obj)
310311
#endif
311312
{
313+
jl_tls_states_t *ptls = jl_get_ptls_states();
312314
// This function modify linfo->fptr in GC safe region.
313315
// This should be fine since the GC won't scan this field.
314-
int8_t gc_state = jl_gc_safe_enter();
316+
int8_t gc_state = jl_gc_safe_enter(ptls);
315317
uv_rwlock_wrlock(&threadsafe);
316318
#ifdef LLVM36
317319
object::section_iterator Section = debugObj.section_begin();
@@ -601,7 +603,7 @@ class JuliaJITEventListener: public JITEventListener
601603
#endif
602604
#endif
603605
uv_rwlock_wrunlock(&threadsafe);
604-
jl_gc_safe_leave(gc_state);
606+
jl_gc_safe_leave(ptls, gc_state);
605607
}
606608

607609
// must implement if we ever start freeing code
@@ -1174,17 +1176,18 @@ int jl_DI_for_fptr(uint64_t fptr, uint64_t *symsize, int64_t *slide, int64_t *se
11741176
extern "C"
11751177
JL_DLLEXPORT jl_value_t *jl_get_dobj_data(uint64_t fptr)
11761178
{
1179+
jl_tls_states_t *ptls = jl_get_ptls_states();
11771180
// Used by Gallium.jl
11781181
const object::ObjectFile *object = NULL;
11791182
DIContext *context;
11801183
int64_t slide, section_slide;
1181-
int8_t gc_state = jl_gc_safe_enter();
1184+
int8_t gc_state = jl_gc_safe_enter(ptls);
11821185
if (!jl_DI_for_fptr(fptr, NULL, &slide, NULL, &object, NULL))
11831186
if (!jl_dylib_DI_for_fptr(fptr, &object, &context, &slide, &section_slide, false, NULL, NULL, NULL, NULL)) {
1184-
jl_gc_safe_leave(gc_state);
1187+
jl_gc_safe_leave(ptls, gc_state);
11851188
return jl_nothing;
11861189
}
1187-
jl_gc_safe_leave(gc_state);
1190+
jl_gc_safe_leave(ptls, gc_state);
11881191
if (object == NULL)
11891192
return jl_nothing;
11901193
return (jl_value_t*)jl_ptr_to_array_1d((jl_value_t*)jl_array_uint8_type,
@@ -1195,8 +1198,9 @@ JL_DLLEXPORT jl_value_t *jl_get_dobj_data(uint64_t fptr)
11951198
extern "C"
11961199
JL_DLLEXPORT uint64_t jl_get_section_start(uint64_t fptr)
11971200
{
1201+
jl_tls_states_t *ptls = jl_get_ptls_states();
11981202
// Used by Gallium.jl
1199-
int8_t gc_state = jl_gc_safe_enter();
1203+
int8_t gc_state = jl_gc_safe_enter(ptls);
12001204
std::map<size_t, ObjectInfo, revcomp> &objmap = jl_jit_events->getObjectMap();
12011205
std::map<size_t, ObjectInfo, revcomp>::iterator fit = objmap.lower_bound(fptr);
12021206

@@ -1212,7 +1216,7 @@ JL_DLLEXPORT uint64_t jl_get_section_start(uint64_t fptr)
12121216
}
12131217
}
12141218
uv_rwlock_rdunlock(&threadsafe);
1215-
jl_gc_safe_leave(gc_state);
1219+
jl_gc_safe_leave(ptls, gc_state);
12161220
return ret;
12171221
}
12181222

src/gc-debug.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,10 @@ static void gc_verify_track(void)
172172
clear_mark(GC_CLEAN);
173173
pre_mark();
174174
gc_mark_object_list(&to_finalize, 0);
175-
gc_mark_object_list(&finalizer_list, 0);
175+
for (int i = 0;i < jl_n_threads;i++) {
176+
jl_tls_states_t *ptls2 = jl_all_tls_states[i];
177+
gc_mark_object_list(&ptls2->finalizers, 0);
178+
}
176179
gc_mark_object_list(&finalizer_list_marked, 0);
177180
visit_mark_stack();
178181
if (lostval_parents.len == 0) {
@@ -215,7 +218,10 @@ void gc_verify(void)
215218
gc_verifying = 1;
216219
pre_mark();
217220
gc_mark_object_list(&to_finalize, 0);
218-
gc_mark_object_list(&finalizer_list, 0);
221+
for (int i = 0;i < jl_n_threads;i++) {
222+
jl_tls_states_t *ptls2 = jl_all_tls_states[i];
223+
gc_mark_object_list(&ptls2->finalizers, 0);
224+
}
219225
gc_mark_object_list(&finalizer_list_marked, 0);
220226
visit_mark_stack();
221227
int clean_len = bits_save[GC_CLEAN].len;

0 commit comments

Comments
 (0)