Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 42 additions & 18 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1666,51 +1666,69 @@ struct CacheFlags
check_bounds::Int
inline::Bool
opt_level::Int
sanitize_memory::Bool
sanitize_thread::Bool
sanitize_address::Bool
end
function CacheFlags(f::UInt8)
function CacheFlags(f::UInt64)
use_pkgimages = Bool(f & 1)
debug_level = Int((f >> 1) & 3)
check_bounds = Int((f >> 3) & 3)
inline = Bool((f >> 5) & 1)
opt_level = Int((f >> 6) & 3) # define OPT_LEVEL in statiddata_utils
CacheFlags(use_pkgimages, debug_level, check_bounds, inline, opt_level)
sanitize_memory = Bool((f >> 8) & 1)
sanitize_thread = Bool((f >> 9) & 1)
sanitize_address = Bool((f >> 10) & 1)
CacheFlags(use_pkgimages, debug_level, check_bounds, inline, opt_level, sanitize_memory, sanitize_thread, sanitize_address)
end
CacheFlags(f::Int) = CacheFlags(UInt8(f))
function CacheFlags(cf::CacheFlags=CacheFlags(ccall(:jl_cache_flags, UInt8, ()));
CacheFlags(f::Int) = CacheFlags(UInt64(f))
function CacheFlags(cf::CacheFlags=CacheFlags(ccall(:jl_cache_flags, UInt64, ()));
use_pkgimages::Union{Nothing,Bool}=nothing,
debug_level::Union{Nothing,Int}=nothing,
check_bounds::Union{Nothing,Int}=nothing,
inline::Union{Nothing,Bool}=nothing,
opt_level::Union{Nothing,Int}=nothing
opt_level::Union{Nothing,Int}=nothing,
sanitize_memory::Union{Nothing,Bool}=nothing,
sanitize_thread::Union{Nothing,Bool}=nothing,
sanitize_address::Union{Nothing,Bool}=nothing,
)
return CacheFlags(
use_pkgimages === nothing ? cf.use_pkgimages : use_pkgimages,
debug_level === nothing ? cf.debug_level : debug_level,
check_bounds === nothing ? cf.check_bounds : check_bounds,
inline === nothing ? cf.inline : inline,
opt_level === nothing ? cf.opt_level : opt_level
opt_level === nothing ? cf.opt_level : opt_level,
sanitize_memory === nothing ? cf.sanitize_memory : sanitize_memory,
sanitize_thread === nothing ? cf.sanitize_thread : sanitize_thread,
sanitize_address === nothing ? cf.sanitize_address : sanitize_address,
)
end
# reflecting jloptions.c defaults
const DefaultCacheFlags = CacheFlags(use_pkgimages=true, debug_level=isdebugbuild() ? 2 : 1, check_bounds=0, inline=true, opt_level=2)
const DefaultCacheFlags = CacheFlags(use_pkgimages=true, debug_level=isdebugbuild() ? 2 : 1, check_bounds=0, inline=true, opt_level=2, sanitize_memory=false, sanitize_thread=false, sanitize_address=false)

function _cacheflag_to_uint8(cf::CacheFlags)::UInt8
f = UInt8(0)
function _cacheflag_to_uint16(cf::CacheFlags)::UInt64
f = UInt64(0)
f |= cf.use_pkgimages << 0
f |= cf.debug_level << 1
f |= cf.check_bounds << 3
f |= cf.inline << 5
f |= cf.opt_level << 6
f |= cf.sanitize_memory << 8
f |= cf.sanitize_thread << 9
f |= cf.sanitize_address << 10
return f
end

function translate_cache_flags(cacheflags::CacheFlags, defaultflags::CacheFlags)
opts = String[]
cacheflags.use_pkgimages != defaultflags.use_pkgimages && push!(opts, cacheflags.use_pkgimages ? "--pkgimages=yes" : "--pkgimages=no")
cacheflags.debug_level != defaultflags.debug_level && push!(opts, "-g$(cacheflags.debug_level)")
cacheflags.check_bounds != defaultflags.check_bounds && push!(opts, ("--check-bounds=auto", "--check-bounds=yes", "--check-bounds=no")[cacheflags.check_bounds + 1])
cacheflags.inline != defaultflags.inline && push!(opts, cacheflags.inline ? "--inline=yes" : "--inline=no")
cacheflags.opt_level != defaultflags.opt_level && push!(opts, "-O$(cacheflags.opt_level)")
cacheflags.use_pkgimages != defaultflags.use_pkgimages && push!(opts, cacheflags.use_pkgimages ? "--pkgimages=yes" : "--pkgimages=no")
cacheflags.debug_level != defaultflags.debug_level && push!(opts, "-g$(cacheflags.debug_level)")
cacheflags.check_bounds != defaultflags.check_bounds && push!(opts, ("--check-bounds=auto", "--check-bounds=yes", "--check-bounds=no")[cacheflags.check_bounds + 1])
cacheflags.inline != defaultflags.inline && push!(opts, cacheflags.inline ? "--inline=yes" : "--inline=no")
cacheflags.opt_level != defaultflags.opt_level && push!(opts, "-O$(cacheflags.opt_level)")
cacheflags.sanitize_memory != defaultflags.sanitize_memory && push!(opts, "--target-sanitize=memory")
cacheflags.sanitize_thread != defaultflags.sanitize_thread && push!(opts, "--target-sanitize=thread")
cacheflags.sanitize_address != defaultflags.sanitize_address && push!(opts, "--target-sanitize=address")
return opts
end

Expand All @@ -1726,6 +1744,12 @@ function show(io::IO, cf::CacheFlags)
print(io, cf.inline)
print(io, ", opt_level=")
print(io, cf.opt_level)
print(io, ", sanitize_memory=")
print(io, cf.sanitize_memory)
print(io, ", sanitize_thread=")
print(io, cf.sanitize_thread)
print(io, ", sanitize_address=")
print(io, cf.sanitize_address)
print(io, ")")
end

Expand Down Expand Up @@ -3133,7 +3157,7 @@ function compilecache_path(pkg::PkgId, prefs_hash::UInt64; flags::CacheFlags=Cac
crc = _crc32c(project)
crc = _crc32c(unsafe_string(JLOptions().image_file), crc)
crc = _crc32c(unsafe_string(JLOptions().julia_bin), crc)
crc = _crc32c(_cacheflag_to_uint8(flags), crc)
crc = _crc32c(_cacheflag_to_uint16(flags), crc)

cpu_target = get(ENV, "JULIA_CPU_TARGET", nothing)
if cpu_target === nothing
Expand Down Expand Up @@ -3402,7 +3426,7 @@ function read_module_list(f::IO, has_buildid_hi::Bool)
end

function _parse_cache_header(f::IO, cachefile::AbstractString)
flags = read(f, UInt8)
flags = read(f, UInt64)
modules = read_module_list(f, false)
totbytes = Int64(read(f, UInt64)) # total bytes for file dependencies + preferences
# read the list of requirements
Expand Down Expand Up @@ -3964,10 +3988,10 @@ end
if isempty(modules)
return true # ignore empty file
end
if @ccall(jl_match_cache_flags(_cacheflag_to_uint8(requested_flags)::UInt8, actual_flags::UInt8)::UInt8) == 0
if @ccall(jl_match_cache_flags(_cacheflag_to_uint16(requested_flags)::UInt64, actual_flags::UInt64)::UInt8) == 0
@debug """
Rejecting cache file $cachefile for $modkey since the flags are mismatched
requested flags: $(requested_flags) [$(_cacheflag_to_uint8(requested_flags))]
requested flags: $(requested_flags) [$(_cacheflag_to_uint16(requested_flags))]
cache file: $(CacheFlags(actual_flags)) [$actual_flags]
"""
record_reason(reasons, "mismatched flags")
Expand Down
3 changes: 3 additions & 0 deletions base/options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ struct JLOptions
task_metrics::Int8
timeout_for_safepoint_straggler_s::Int16
gc_sweep_always_full::Int8
target_sanitize_memory::Int8
target_sanitize_thread::Int8
target_sanitize_address::Int8
end

# This runs early in the sysimage != is not defined yet
Expand Down
19 changes: 17 additions & 2 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,32 @@ struct CodegenParams
"""
force_emit_all::Cint

"""
When enabled, run the MemorySanitizer pass.
"""
sanitize_memory::Cint
"""
When enabled, run the ThreadSanitizer pass.
"""
sanitize_thread::Cint
"""
When enabled, run the AddressSanitizer pass.
"""
sanitize_address::Cint

function CodegenParams(; track_allocations::Bool=true, code_coverage::Bool=true,
prefer_specsig::Bool=false,
gnu_pubnames::Bool=true, debug_info_kind::Cint = default_debug_info_kind(),
debug_info_level::Cint = Cint(JLOptions().debug_level), safepoint_on_entry::Bool=true,
gcstack_arg::Bool=true, use_jlplt::Bool=true, force_emit_all::Bool=false)
gcstack_arg::Bool=true, use_jlplt::Bool=true, force_emit_all::Bool=false,
sanitize_memory::Bool=false, sanitize_thread::Bool=false, sanitize_address::Bool=false)
return new(
Cint(track_allocations), Cint(code_coverage),
Cint(prefer_specsig),
Cint(gnu_pubnames), debug_info_kind,
debug_info_level, Cint(safepoint_on_entry),
Cint(gcstack_arg), Cint(use_jlplt), Cint(force_emit_all))
Cint(gcstack_arg), Cint(use_jlplt), Cint(force_emit_all),
Cint(sanitize_memory), Cint(sanitize_thread), Cint(sanitize_address))
end
end

Expand Down
9 changes: 9 additions & 0 deletions base/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@ function julia_cmd(julia=joinpath(Sys.BINDIR, julia_exename()); cpu_target::Unio
if opts.use_sysimage_native_code == 0
push!(addflags, "--sysimage-native-code=no")
end
if opts.target_sanitize_memory == 1
push!(addflags, "--target-sanitize=memory")
end
if opts.target_sanitize_thread == 1
push!(addflags, "--target-sanitize=thread")
end
if opts.target_sanitize_address == 1
push!(addflags, "--target-sanitize=address")
end
return `$julia -C $cpu_target -J$image_file $addflags`
end

Expand Down
17 changes: 14 additions & 3 deletions src/aotcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ static void resolve_workqueue(jl_codegen_params_t &params, egal_set &method_root
// emit specsig-to-(jl)invoke conversion
proto.decl->setLinkage(GlobalVariable::InternalLinkage);
//protodecl->setAlwaysInline();
jl_init_function(proto.decl, params.TargetTriple);
jl_init_function(proto.decl, params);
jl_method_instance_t *mi = jl_get_ci_mi(codeinst);
size_t nrealargs = jl_nparams(mi->specTypes); // number of actual arguments being passed
bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure;
Expand Down Expand Up @@ -693,6 +693,9 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm
compiler_start_time = jl_hrtime();

jl_cgparams_t cgparams = jl_default_cgparams;
cgparams.sanitize_memory = jl_options.target_sanitize_memory;
cgparams.sanitize_thread = jl_options.target_sanitize_thread;
cgparams.sanitize_address = jl_options.target_sanitize_address;
size_t compile_for[] = { jl_typeinf_world, world };
int compiler_world = 1;
if (trim || compile_for[0] == 0)
Expand Down Expand Up @@ -1565,7 +1568,11 @@ static AOTOutputs add_output_impl(Module &M, TargetMachine &SourceTM, ShardTimer
SourceTM.getCodeModel(),
SourceTM.getOptLevel()));
fixupTM(*PMTM);
NewPM optimizer{std::move(PMTM), getOptLevel(jl_options.opt_level), OptimizationOptions::defaults(true, true)};
auto options = OptimizationOptions::defaults(true, true);
options.sanitize_memory = jl_options.target_sanitize_memory;
options.sanitize_thread = jl_options.target_sanitize_thread;
options.sanitize_address = jl_options.target_sanitize_address;
NewPM optimizer{std::move(PMTM), getOptLevel(jl_options.opt_level), options};
optimizer.run(M);
assert(!verifyLLVMIR(M));
bool inject_aliases = false;
Expand Down Expand Up @@ -2531,7 +2538,11 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t *dump, jl_method_instance_t *mi, jl_
}
assert(!verifyLLVMIR(*m.getModuleUnlocked()));
if (optimize) {
NewPM PM{jl_ExecutionEngine->cloneTargetMachine(), getOptLevel(jl_options.opt_level)};
auto opts = OptimizationOptions::defaults();
opts.sanitize_memory = params.sanitize_memory;
opts.sanitize_thread = params.sanitize_thread;
opts.sanitize_address = params.sanitize_address;
NewPM PM{jl_ExecutionEngine->cloneTargetMachine(), getOptLevel(jl_options.opt_level), opts};
//Safe b/c context lock is held by output
PM.run(*m.getModuleUnlocked());
assert(!verifyLLVMIR(*m.getModuleUnlocked()));
Expand Down
Loading