Skip to content

Commit 0ea64c0

Browse files
committed
Push fixes + assume effects
1 parent 970cc46 commit 0ea64c0

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

base/c.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,6 @@ macro ccall(expr)
409409
return ccall_macro_lower(:ccall, ccall_macro_parse(expr)...)
410410
end
411411

412-
macro ccall_effects(effects::UInt16, expr)
413-
return ccall_macro_lower((:ccall, effects, false), ccall_macro_parse(expr)...)
412+
macro ccall_effects(effects::UInt16, gc_safe::Bool, expr)
413+
return ccall_macro_lower((:ccall, effects, gc_safe), ccall_macro_parse(expr)...)
414414
end

base/expr.jl

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ The following `setting`s are supported.
516516
- `:foldable`
517517
- `:removable`
518518
- `:total`
519-
519+
- `:gc_safe`
520520
# Extended help
521521
522522
---
@@ -750,6 +750,13 @@ the following other `setting`s:
750750
number of effect overrides apply to a set of functions, a custom macro is
751751
recommended over the use of `:total`.
752752
753+
---
754+
## `:gc_safe`
755+
756+
This `setting` can only be applied to `@ccall` expressions. It asserts that the
757+
`@ccall` is safe to execute concurrently with the garbage collector. This means that it must not
758+
call into the julia runtime.
759+
753760
---
754761
## Negated effects
755762
@@ -759,12 +766,13 @@ the call is generally total, it may however throw.
759766
"""
760767
macro assume_effects(args...)
761768
lastex = args[end]
762-
override = compute_assumed_settings(args[begin:end-1])
769+
override, gc_safe = compute_assumed_settings(args[begin:end-1])
763770
if is_function_def(unwrap_macrocalls(lastex))
764771
return esc(pushmeta!(lastex::Expr, form_purity_expr(override)))
765772
elseif isexpr(lastex, :macrocall) && lastex.args[1] === Symbol("@ccall")
766773
lastex.args[1] = GlobalRef(Base, Symbol("@ccall_effects"))
767774
insert!(lastex.args, 3, encode_effects_override(override))
775+
insert!(lastex.args, 4, gc_safe)
768776
return esc(lastex)
769777
end
770778
override′ = compute_assumed_setting(override, lastex)
@@ -783,12 +791,19 @@ end
783791

784792
function compute_assumed_settings(settings)
785793
override = EffectsOverride()
794+
gc_safe = false
786795
for setting in settings
796+
# This way of parsing is slightly annoying, but it's to avoid extra complexity for EffectOverride
797+
gc_safe2, found = compute_gc_safe(setting)
798+
if found
799+
gc_safe = gc_safe2
800+
continue
801+
end
787802
override = compute_assumed_setting(override, setting)
788803
override === nothing &&
789804
throw(ArgumentError("`@assume_effects $setting` not supported"))
790805
end
791-
return override
806+
return override, gc_safe
792807
end
793808

794809
struct EffectsOverride
@@ -835,6 +850,18 @@ end
835850

836851
const NUM_EFFECTS_OVERRIDES = 11 # sync with julia.h
837852

853+
function compute_gc_safe(setting)
854+
if setting === :gc_safe
855+
return (gc_safe=true, found=true)
856+
elseif isexpr(setting, :call) && setting.args[1] === :(!)
857+
gc_safe2, found2 = compute_gc_safe(setting.args[2])
858+
return (gc_safe=(!gc_safe2), found=found2)
859+
elseif isa(setting, QuoteNode)
860+
return compute_gc_safe(setting.value)
861+
end
862+
return (gc_safe=false, found=false)
863+
end
864+
838865
function compute_assumed_setting(override::EffectsOverride, @nospecialize(setting), val::Bool=true)
839866
if isexpr(setting, :call) && setting.args[1] === :(!)
840867
return compute_assumed_setting(override, setting.args[2], !val)

src/ccall.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// --- the ccall, cglobal, and llvm intrinsics ---
44

55
// Mark our stats as being from ccall
6+
#include "julia.h"
67
#undef DEBUG_TYPE
78
#define DEBUG_TYPE "julia_irgen_ccall"
89

@@ -1431,13 +1432,12 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
14311432
// TODO: Can we introduce a intrinisc token = @julia.gc_safe_begin()
14321433
// and "grow" gc safe regions so that we minimize the overhead?
14331434
bool gc_safe = false;
1434-
assert(jl_is_symbol(cc_sym));
14351435
if (jl_is_symbol(jlcc)) {
14361436
cc_sym = (jl_sym_t*)jlcc;
14371437
}
14381438
else if (jl_is_tuple(jlcc)) {
14391439
cc_sym = (jl_sym_t*)jl_get_nth_field_noalloc(jlcc, 0);
1440-
gc_safe = jl_unbox_bool(jl_get_nth_field_noalloc(jlcc, 2));
1440+
gc_safe = jl_unbox_bool(jl_get_nth_field_checked(jlcc, 2));
14411441
}
14421442
assert(jl_is_symbol(cc_sym));
14431443
native_sym_arg_t symarg = {};

test/strings/basic.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,8 +1249,8 @@ end
12491249
@test !Core.Compiler.is_removable_if_unused(e) || (f, Ts)
12501250
end
12511251
@test_throws ArgumentError Symbol("a\0a")
1252-
1253-
@test Base._string_n_override == Base.encode_effects_override(Base.compute_assumed_settings((:total, :(!:consistent))))
1252+
override, _ = Base.compute_assumed_settings((:total, :(!:consistent)))
1253+
@test Base._string_n_override == Base.encode_effects_override(override)
12541254
end
12551255

12561256
@testset "Ensure UTF-8 DFA can never leave invalid state" begin

0 commit comments

Comments
 (0)