Skip to content

Commit 7e2e6c9

Browse files
authored
Merge pull request #23562 from JuliaLang/kf/gcuse
Add gc use intrinisic
2 parents 9cdec25 + 797e87b commit 7e2e6c9

File tree

7 files changed

+45
-17
lines changed

7 files changed

+45
-17
lines changed

base/boot.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,4 +438,6 @@ show(@nospecialize a) = show(STDOUT, a)
438438
print(@nospecialize a...) = print(STDOUT, a...)
439439
println(@nospecialize a...) = println(STDOUT, a...)
440440

441+
gcuse(@nospecialize a) = ccall(:jl_gc_use, Void, (Any,), a)
442+
441443
ccall(:jl_set_istopmod, Void, (Any, Bool), Core, true)

base/strings/string.jl

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ String(s::Symbol) = unsafe_string(Cstring(s))
5959
pointer(s::String) = unsafe_convert(Ptr{UInt8}, s)
6060
pointer(s::String, i::Integer) = pointer(s)+(i-1)
6161

62+
function unsafe_load(s::String, i::Integer=1)
63+
ptr = pointer(s, i)
64+
r = unsafe_load(ptr)
65+
Core.gcuse(s)
66+
r
67+
end
68+
6269
sizeof(s::String) = Core.sizeof(s)
6370

6471
"""
@@ -73,7 +80,7 @@ codeunit(s::AbstractString, i::Integer)
7380
@boundscheck if (i < 1) | (i > sizeof(s))
7481
throw(BoundsError(s,i))
7582
end
76-
unsafe_load(pointer(s),i)
83+
unsafe_load(s, i)
7784
end
7885

7986
write(io::IO, s::String) = unsafe_write(io, pointer(s), reinterpret(UInt, sizeof(s)))
@@ -160,26 +167,24 @@ const utf8_trailing = [
160167
## required core functionality ##
161168

162169
function endof(s::String)
163-
p = pointer(s)
164170
i = sizeof(s)
165-
while i > 0 && is_valid_continuation(unsafe_load(p,i))
171+
while i > 0 && is_valid_continuation(unsafe_load(s, i))
166172
i -= 1
167173
end
168174
i
169175
end
170176

171177
function length(s::String)
172-
p = pointer(s)
173178
cnum = 0
174179
for i = 1:sizeof(s)
175-
cnum += !is_valid_continuation(unsafe_load(p,i))
180+
cnum += !is_valid_continuation(unsafe_load(s, i))
176181
end
177182
cnum
178183
end
179184

180-
@noinline function slow_utf8_next(p::Ptr{UInt8}, b::UInt8, i::Int, l::Int)
185+
@noinline function slow_utf8_next(s::String, b::UInt8, i::Int, l::Int)
181186
if is_valid_continuation(b)
182-
throw(UnicodeError(UTF_ERR_INVALID_INDEX, i, unsafe_load(p,i)))
187+
throw(UnicodeError(UTF_ERR_INVALID_INDEX, i, unsafe_load(s, i)))
183188
end
184189
trailing = utf8_trailing[b + 1]
185190
if l < i + trailing
@@ -188,7 +193,7 @@ end
188193
c::UInt32 = 0
189194
for j = 1:(trailing + 1)
190195
c <<= 6
191-
c += unsafe_load(p,i)
196+
c += unsafe_load(s, i)
192197
i += 1
193198
end
194199
c -= utf8_offset[trailing + 1]
@@ -206,12 +211,11 @@ done(s::String, state) = state > sizeof(s)
206211
@boundscheck if (i < 1) | (i > sizeof(s))
207212
throw(BoundsError(s,i))
208213
end
209-
p = pointer(s)
210-
b = unsafe_load(p, i)
214+
b = unsafe_load(s, i)
211215
if b < 0x80
212216
return Char(b), i + 1
213217
end
214-
return slow_utf8_next(p, b, i, sizeof(s))
218+
return slow_utf8_next(s, b, i, sizeof(s))
215219
end
216220

217221
function first_utf8_byte(ch::Char)
@@ -225,8 +229,7 @@ end
225229

226230
function reverseind(s::String, i::Integer)
227231
j = sizeof(s) + 1 - i
228-
p = pointer(s)
229-
while is_valid_continuation(unsafe_load(p,j))
232+
while is_valid_continuation(unsafe_load(s, j))
230233
j -= 1
231234
end
232235
return j
@@ -235,7 +238,7 @@ end
235238
## overload methods for efficiency ##
236239

237240
isvalid(s::String, i::Integer) =
238-
(1 <= i <= sizeof(s)) && !is_valid_continuation(unsafe_load(pointer(s),i))
241+
(1 <= i <= sizeof(s)) && !is_valid_continuation(unsafe_load(s, i))
239242

240243
function getindex(s::String, r::UnitRange{Int})
241244
isempty(r) && return ""
@@ -438,7 +441,7 @@ function repeat(s::String, r::Integer)
438441
n = sizeof(s)
439442
out = _string_n(n*r)
440443
if n == 1 # common case: repeating a single ASCII char
441-
ccall(:memset, Ptr{Void}, (Ptr{UInt8}, Cint, Csize_t), out, unsafe_load(pointer(s)), r)
444+
ccall(:memset, Ptr{Void}, (Ptr{UInt8}, Cint, Csize_t), out, unsafe_load(s), r)
442445
else
443446
for i=1:r
444447
unsafe_copy!(pointer(out, 1+(i-1)*n), pointer(s), n)

src/ccall.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,13 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
16871687
emit_signal_fence(ctx);
16881688
return ghostValue(jl_void_type);
16891689
}
1690+
else if (is_libjulia_func(jl_gc_use)) {
1691+
assert(lrt == T_void);
1692+
assert(!isVa && !llvmcall && nargt == 1);
1693+
ctx.builder.CreateCall(prepare_call(gc_use_func), {decay_derived(boxed(ctx, argv[0]))});
1694+
JL_GC_POP();
1695+
return ghostValue(jl_void_type);
1696+
}
16901697
else if (_is_libjulia_func((uintptr_t)ptls_getter, "jl_get_ptls_states")) {
16911698
assert(lrt == T_pint8);
16921699
assert(!isVa && !llvmcall && nargt == 0);

src/codegen.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ static GlobalVariable *jlgetworld_global;
356356

357357
// placeholder functions
358358
static Function *gcroot_flush_func;
359+
static Function *gc_use_func;
359360
static Function *except_enter_func;
360361
static Function *pointer_from_objref_func;
361362

@@ -6488,6 +6489,12 @@ static void init_julia_llvm_env(Module *m)
64886489
"julia.gcroot_flush");
64896490
add_named_global(gcroot_flush_func, (void*)NULL, /*dllimport*/false);
64906491

6492+
gc_use_func = Function::Create(FunctionType::get(T_void,
6493+
ArrayRef<Type*>(PointerType::get(T_jlvalue, AddressSpace::Derived)), false),
6494+
Function::ExternalLinkage,
6495+
"julia.gc_use");
6496+
add_named_global(gc_use_func, (void*)NULL, /*dllimport*/false);
6497+
64916498
pointer_from_objref_func = Function::Create(FunctionType::get(T_pjlvalue,
64926499
ArrayRef<Type*>(PointerType::get(T_jlvalue, AddressSpace::Derived)), false),
64936500
Function::ExternalLinkage,

src/julia.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ JL_DLLEXPORT jl_value_t *jl_gc_alloc_1w(void);
649649
JL_DLLEXPORT jl_value_t *jl_gc_alloc_2w(void);
650650
JL_DLLEXPORT jl_value_t *jl_gc_alloc_3w(void);
651651
JL_DLLEXPORT jl_value_t *jl_gc_allocobj(size_t sz);
652+
JL_DLLEXPORT void jl_gc_use(jl_value_t *a);
652653

653654
JL_DLLEXPORT void jl_clear_malloc_data(void);
654655

src/llvm-late-gc-lowering.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ struct LateLowerGCFrame: public FunctionPass {
321321
MDNode *tbaa_tag;
322322
Function *ptls_getter;
323323
Function *gc_flush_func;
324+
Function *gc_use_func;
324325
Function *pointer_from_objref_func;
325326
Function *alloc_obj_func;
326327
Function *pool_alloc_func;
@@ -758,7 +759,8 @@ State LateLowerGCFrame::LocalScan(Function &F) {
758759
}
759760
if (auto callee = CI->getCalledFunction()) {
760761
// Known functions emitted in codegen that are not safepoints
761-
if (callee == pointer_from_objref_func || callee->getName() == "memcmp") {
762+
if (callee == pointer_from_objref_func || callee == gc_use_func ||
763+
callee->getName() == "memcmp") {
762764
continue;
763765
}
764766
}
@@ -1150,7 +1152,8 @@ bool LateLowerGCFrame::CleanupIR(Function &F) {
11501152
}
11511153
CallingConv::ID CC = CI->getCallingConv();
11521154
auto callee = CI->getCalledValue();
1153-
if (gc_flush_func != nullptr && callee == gc_flush_func) {
1155+
if ((gc_flush_func != nullptr && callee == gc_flush_func) ||
1156+
(gc_use_func != nullptr && callee == gc_use_func)) {
11541157
/* No replacement */
11551158
} else if (pointer_from_objref_func != nullptr && callee == pointer_from_objref_func) {
11561159
auto *ASCI = new AddrSpaceCastInst(CI->getOperand(0),
@@ -1418,6 +1421,7 @@ static void addRetNoAlias(Function *F)
14181421
bool LateLowerGCFrame::doInitialization(Module &M) {
14191422
ptls_getter = M.getFunction("jl_get_ptls_states");
14201423
gc_flush_func = M.getFunction("julia.gcroot_flush");
1424+
gc_use_func = M.getFunction("julia.gc_use");
14211425
pointer_from_objref_func = M.getFunction("julia.pointer_from_objref");
14221426
auto &ctx = M.getContext();
14231427
T_size = M.getDataLayout().getIntPtrType(ctx);

src/rtutils.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,10 @@ JL_DLLEXPORT jl_value_t *jl_value_ptr(jl_value_t *a)
305305
{
306306
return a;
307307
}
308+
JL_DLLEXPORT void jl_gc_use(jl_value_t *a)
309+
{
310+
(void)a;
311+
}
308312

309313
// parsing --------------------------------------------------------------------
310314

0 commit comments

Comments
 (0)