Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make logging work with trimming #55166

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f85fa88
Implement changes to the runtime that allow for building small binaries,
gbaraldi Jun 11, 2024
6e11f0a
Also make reinit_stdio overloadable
gbaraldi Jun 12, 2024
cb72878
Implement example driver and simple tests
gbaraldi Jun 12, 2024
e812e34
Less invasive changes to base to make hello world work
gbaraldi Jun 12, 2024
999b6bf
Fix some typos and refactor cli usage to only use static-call-graph. …
gbaraldi Jun 13, 2024
138e3c6
make argument to --static-call-graph optional, improve help text
JeffBezanson Jun 18, 2024
4d058f7
misc formatting and cleanup
JeffBezanson Jun 20, 2024
4280270
Check all builtins for potential dynamic dispatches
gbaraldi Jun 25, 2024
2ef1a0b
Fix typos in the driver and exit with exit(1)
gbaraldi Jun 27, 2024
7f7ddd9
Make stacktrace printing robust and add overload to init_project to a…
gbaraldi Jun 27, 2024
9935a87
fix warning for print_retainers by ifdef'ing it out
JeffBezanson Jun 27, 2024
80c047d
Save current state of the branch.
gbaraldi Jul 1, 2024
d1ac612
WIP
JeffBezanson Jul 2, 2024
bf85687
Add default --static-call-graph option
gbaraldi Jul 2, 2024
59ae2d0
avoid unnecessary inexact check in `write(::IO, ::String)`
JeffBezanson Jul 5, 2024
1d2182e
don't compile for typeinf world with static-call-graph
JeffBezanson Jul 5, 2024
27dca02
disable unoptimize_throw_blocks for trimming
JeffBezanson Jul 5, 2024
08ac726
rename option to --trim
JeffBezanson Jul 5, 2024
76d1467
wip
JeffBezanson Jul 10, 2024
7e94b0f
fixes for threads and tasks with trimming
JeffBezanson Jul 13, 2024
5f54b63
Fix unsafe-warn mutiple stacktrace output
gbaraldi Jul 12, 2024
c77c2ab
Get lib example working, create build script (#55104)
timholy Jul 15, 2024
feefbc4
fix whitespace
JeffBezanson Jul 18, 2024
ea1bf6a
fix CodegenParams ctor
JeffBezanson Jul 18, 2024
f069cd2
rm cache_method from header
JeffBezanson Jul 19, 2024
c790432
juliac: add logging.jl example + improve Logging type-stability (incl…
topolarity Jul 7, 2024
30006ce
juliac: add preliminary StyledStrings support
topolarity Jul 11, 2024
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
36 changes: 20 additions & 16 deletions base/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,25 @@ function profile_printing_listener(cond::Base.AsyncCondition)
nothing
end

function start_profile_listener()
cond = Base.AsyncCondition()
Base.uv_unref(cond.handle)
t = errormonitor(Threads.@spawn(profile_printing_listener(cond)))
atexit() do
# destroy this callback when exiting
ccall(:jl_set_peek_cond, Cvoid, (Ptr{Cvoid},), C_NULL)
# this will prompt any ongoing or pending event to flush also
close(cond)
# error-propagation is not needed, since the errormonitor will handle printing that better
_wait(t)
end
finalizer(cond) do c
# if something goes south, still make sure we aren't keeping a reference in C to this
ccall(:jl_set_peek_cond, Cvoid, (Ptr{Cvoid},), C_NULL)
end
ccall(:jl_set_peek_cond, Cvoid, (Ptr{Cvoid},), cond.handle)
end

function __init__()
# Base library init
global _atexit_hooks_finished = false
Expand All @@ -636,22 +655,7 @@ function __init__()
# Profiling helper
@static if !Sys.iswindows()
# triggering a profile via signals is not implemented on windows
cond = Base.AsyncCondition()
Base.uv_unref(cond.handle)
t = errormonitor(Threads.@spawn(profile_printing_listener(cond)))
atexit() do
# destroy this callback when exiting
ccall(:jl_set_peek_cond, Cvoid, (Ptr{Cvoid},), C_NULL)
# this will prompt any ongoing or pending event to flush also
close(cond)
# error-propagation is not needed, since the errormonitor will handle printing that better
_wait(t)
end
finalizer(cond) do c
# if something goes south, still make sure we aren't keeping a reference in C to this
ccall(:jl_set_peek_cond, Cvoid, (Ptr{Cvoid},), C_NULL)
end
ccall(:jl_set_peek_cond, Cvoid, (Ptr{Cvoid},), cond.handle)
start_profile_listener()
end
_require_world_age[] = get_world_counter()
# Prevent spawned Julia process from getting stuck waiting on Tracy to connect.
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ using Core: ARGS, include
using Core.Compiler: >, getindex, length

MAX_METHODS::Int = 3
UNOPTIMIZE_THROW_BLOCKS::Bool = true
UNOPTIMIZE_THROW_BLOCKS::Bool = false

if length(ARGS) > 2 && ARGS[2] === "--buildsettings"
include(BuildSettings, ARGS[3])
Expand Down
9 changes: 9 additions & 0 deletions base/experimental.jl
Original file line number Diff line number Diff line change
Expand Up @@ -457,4 +457,13 @@ without adding them to the global method table.
"""
:@MethodTable

function entrypoint(@nospecialize(f), @nospecialize(argtypes::Tuple))
entrypoint(Tuple{Core.Typeof(f), argtypes...})
end

function entrypoint(@nospecialize(argt::Type))
ccall(:jl_add_entrypoint, Int32, (Any,), argt)
nothing
end

end
3 changes: 2 additions & 1 deletion base/libuv.jl
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ function uv_return_spawn end
function uv_asynccb end
function uv_timercb end

function reinit_stdio()
reinit_stdio() = _reinit_stdio()
function _reinit_stdio()
global stdin = init_stdio(ccall(:jl_stdin_stream, Ptr{Cvoid}, ()))::IO
global stdout = init_stdio(ccall(:jl_stdout_stream, Ptr{Cvoid}, ()))::IO
global stderr = init_stdio(ccall(:jl_stderr_stream, Ptr{Cvoid}, ()))::IO
Expand Down
96 changes: 56 additions & 40 deletions base/logging/ConsoleLogger.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,28 @@ struct ConsoleLogger <: AbstractLogger
meta_formatter
show_limited::Bool
right_justify::Int
message_limits::Dict{Any,Int}
message_limits::Dict{Symbol,Int}
end
function ConsoleLogger(stream::IO, min_level=Info;
meta_formatter=default_metafmt, show_limited=true,
right_justify=0)
ConsoleLogger(stream, min_level, meta_formatter,
show_limited, right_justify, Dict{Any,Int}())
show_limited, right_justify, Dict{Symbol,Int}())
end
function ConsoleLogger(min_level=Info;
meta_formatter=default_metafmt, show_limited=true,
right_justify=0)
ConsoleLogger(closed_stream, min_level, meta_formatter,
show_limited, right_justify, Dict{Any,Int}())
show_limited, right_justify, Dict{Symbol,Int}())
end


shouldlog(logger::ConsoleLogger, level, _module, group, id) =
get(logger.message_limits, id, 1) > 0
function shouldlog(logger::ConsoleLogger, level::LogLevel, _module::Union{Module,Nothing}, group::Symbol, id::Symbol, maxlog::Union{Int,Nothing})
get(logger.message_limits, id, 1) <= 0 && return false
maxlog === nothing && return true
remaining = get!(logger.message_limits, id, maxlog)
logger.message_limits[id] = remaining - 1
return remaining > 0
end

min_enabled_level(logger::ConsoleLogger) = logger.min_level

Expand All @@ -64,7 +68,7 @@ function default_logcolor(level::LogLevel)
Base.error_color()
end

function default_metafmt(level::LogLevel, _module, group, id, file, line)
function default_metafmt(level::LogLevel, _module::Union{Module,Nothing}, group::Symbol, id::Symbol, file::Union{String,Nothing}, line::Union{UnitRange{Int},Int,Nothing})
@nospecialize
color = default_logcolor(level)
prefix = string(level == Warn ? "Warning" : string(level), ':')
Expand All @@ -75,7 +79,7 @@ function default_metafmt(level::LogLevel, _module, group, id, file, line)
_module !== nothing && (suffix *= " ")
suffix *= contractuser(file)::String
if line !== nothing
suffix *= ":$(isa(line, UnitRange) ? "$(first(line))-$(last(line))" : line)"
suffix *= ":$(isa(line, UnitRange{Int}) ? "$(first(line))-$(last(line))" : line)"
end
end
!isempty(suffix) && (suffix = "@ " * suffix)
Expand Down Expand Up @@ -103,45 +107,54 @@ function termlength(str)
return N
end

function handle_message(logger::ConsoleLogger, level::LogLevel, message, _module, group, id,
filepath, line; kwargs...)
@nospecialize
hasmaxlog = haskey(kwargs, :maxlog) ? 1 : 0
maxlog = get(kwargs, :maxlog, nothing)
if maxlog isa Core.BuiltinInts
remaining = get!(logger.message_limits, id, Int(maxlog)::Int)
logger.message_limits[id] = remaining - 1
remaining > 0 || return
termlength(str::Base.AnnotatedString) = textwidth(str)

function make_normalization_context(logger::ConsoleLogger, nkwargs::Int)
stream = logger.stream
dsize = displaysize(stream)::Tuple{Int,Int}
valbuf = IOBuffer()
rows_per_value = max(1, dsize[1] ÷ (nkwargs + 1))
valio = IOContext(IOContext(valbuf, stream),
:displaysize => (rows_per_value, dsize[2] - 5),
:limit => logger.show_limited)
return (valbuf, valio)
end

function normalize_message(logger::ConsoleLogger, (valbuf, valio)::Tuple{IOBuffer, IOContext}, message_::Any)
message = string(message_)
if Base._isannotated(message) && !isempty(Base.annotations(message))
return Base.AnnotatedString(String(message), Base.annotations(message))::Base.AnnotatedString{String}
else
return String(message)::String
end
end

function normalize_kwarg(logger::ConsoleLogger, (valbuf, valio)::Tuple{IOBuffer, IOContext}, key::Symbol, value::Any)
showvalue(valio, value)
return String(take!(valbuf))::String
end

function handle_message(logger::ConsoleLogger, level::LogLevel, message::Union{String,Base.AnnotatedString{String}}, _module::Union{Module,Nothing},
group::Symbol, id::Symbol, filepath::Union{String,Nothing}, line::Union{UnitRange{Int},Int,Nothing}; kwargs...)
@nospecialize
# Generate a text representation of the message and all key value pairs,
# split into lines. This is specialised to improve type inference,
# and reduce the risk of resulting method invalidations.
message = string(message)
msglines = if Base._isannotated(message) && !isempty(Base.annotations(message))
message = Base.AnnotatedString(String(message), Base.annotations(message))
@NamedTuple{indent::Int, msg::Union{SubString{Base.AnnotatedString{String}}, SubString{String}}}[
(indent=0, msg=l) for l in split(chomp(message), '\n')]
else
[(indent=0, msg=l) for l in split(
chomp(convert(String, message)::String), '\n')]
end
stream::IO = logger.stream
if !(isopen(stream)::Bool)
stream = stderr
end
dsize = displaysize(stream)::Tuple{Int,Int}
MaybeAnnotatedSubString = Union{SubString{Base.AnnotatedString{String}}, SubString{String}}
msglines = @NamedTuple{indent::Int, msg::MaybeAnnotatedSubString}[
@NamedTuple{indent::Int, msg::MaybeAnnotatedSubString}((0,l)) for l in split(chomp(message), '\n')
]
# stream::IO = logger.stream
# if !(isopen(stream)::Bool)
# stream = stderr
# end
stream = Core.stderr
nkwargs = length(kwargs)::Int
if nkwargs > hasmaxlog
if nkwargs > 0
valbuf = IOBuffer()
rows_per_value = max(1, dsize[1] ÷ (nkwargs + 1 - hasmaxlog))
valio = IOContext(IOContext(valbuf, stream),
:displaysize => (rows_per_value, dsize[2] - 5),
:limit => logger.show_limited)
for (key, val) in kwargs
key === :maxlog && continue
showvalue(valio, val)
vallines = split(String(take!(valbuf)), '\n')
vallines = split(val::String, '\n')
if length(vallines) == 1
push!(msglines, (indent=2, msg=SubString("$key = $(vallines[1])")))
else
Expand All @@ -153,13 +166,15 @@ function handle_message(logger::ConsoleLogger, level::LogLevel, message, _module

# Format lines as text with appropriate indentation and with a box
# decoration on the left.
color, prefix, suffix = logger.meta_formatter(level, _module, group, id, filepath, line)::Tuple{Union{Symbol,Int},String,String}
# color, prefix, suffix = logger.meta_formatter(level, _module, group, id, filepath, line)::Tuple{Union{Symbol,Int},String,String}
color, prefix, suffix = default_metafmt(level, _module, group, id, filepath, line)::Tuple{Union{Symbol,Int},String,String}
minsuffixpad = 2
buf = IOBuffer()
iob = IOContext(buf, stream)
nonpadwidth = 2 + (isempty(prefix) || length(msglines) > 1 ? 0 : length(prefix)+1) +
msglines[end].indent + termlength(msglines[end].msg) +
(isempty(suffix) ? 0 : length(suffix)+minsuffixpad)
dsize = displaysize(stream)::Tuple{Int,Int}
justify_width = min(logger.right_justify, dsize[2])
if nonpadwidth > justify_width && !isempty(suffix)
push!(msglines, (indent=0, msg=SubString("")))
Expand All @@ -173,7 +188,8 @@ function handle_message(logger::ConsoleLogger, level::LogLevel, message, _module
"└ "
printstyled(iob, boxstr, bold=true, color=color)
if i == 1 && !isempty(prefix)
printstyled(iob, prefix, " ", bold=true, color=color)
printstyled(iob, prefix, bold=true, color=color)
print(iob, " ")
end
print(iob, " "^indent, msg)
if i == length(msglines) && !isempty(suffix)
Expand Down
Loading
Loading