Skip to content

Commit 04a3dfd

Browse files
committed
Prevent more compile latency in Core parser hooks
1 parent d105724 commit 04a3dfd

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

src/hooks.jl

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
# World age which the parser will be invoked in.
2-
# Set to typemax(UInt) to invoke in the world of the caller.
3-
const _parser_world_age = Ref{UInt}(typemax(UInt))
1+
# This file provides an adaptor to match the API expected by the Julia runtime
2+
# code in the binding Core._parse
3+
4+
# Use caller's world age.
5+
const _caller_world = typemax(UInt)
6+
const _parser_world_age = Ref{UInt}(_caller_world)
47

5-
# Adaptor for the API/ABI expected by the Julia runtime code.
68
function core_parser_hook(code, filename, lineno, offset, options)
7-
if _parser_world_age[] != typemax(UInt)
8-
Base.invoke_in_world(_parser_world_age[], _core_parser_hook,
9+
# `hook` is always _core_parser_hook, but that's hidden from the compiler
10+
# via a Ref to prevent invalidation / recompilation when other packages are
11+
# loaded. This wouldn't seem like it should be necessary given the use of
12+
# invoke_in_world, but it is in Julia-1.7.3. I'm not sure exactly which
13+
# latency it's removing.
14+
hook = _core_parser_hook_ref[]
15+
if _parser_world_age[] != _caller_world
16+
Base.invoke_in_world(_parser_world_age[], hook,
917
code, filename, lineno, offset, options)
1018
else
11-
_core_parser_hook(code, filename, lineno, offset, options)
19+
hook(code, filename, lineno, offset, options)
1220
end
1321
end
1422

@@ -113,10 +121,13 @@ end
113121

114122
# Hack:
115123
# Meta.parse() attempts to construct a ParseError from a string if it receives
116-
# `Expr(:error)`.
124+
# `Expr(:error)`. Add an override to the ParseError constructor to prevent this.
125+
# FIXME: Improve this in Base somehow?
117126
Base.Meta.ParseError(e::JuliaSyntax.ParseError) = e
118127

119128
const _default_parser = Core._parse
129+
# NB: Never reassigned, but the compiler doesn't know this!
130+
const _core_parser_hook_ref = Ref{Function}(_core_parser_hook)
120131

121132
"""
122133
enable_in_core!([enable=true; freeze_world_age, debug_filename])
@@ -134,7 +145,7 @@ Keyword arguments:
134145
"""
135146
function enable_in_core!(enable=true; freeze_world_age = true,
136147
debug_filename = get(ENV, "JULIA_SYNTAX_DEBUG_FILE", nothing))
137-
_parser_world_age[] = freeze_world_age ? Base.get_world_counter() : typemax(UInt)
148+
_parser_world_age[] = freeze_world_age ? Base.get_world_counter() : _caller_world
138149
if enable && !isnothing(debug_filename)
139150
_debug_log[] = open(debug_filename, "w")
140151
elseif !enable && !isnothing(_debug_log[])

0 commit comments

Comments
 (0)