Skip to content

Commit 03dfc52

Browse files
committed
performance: mark REPL and Doc code as non-specializeable
Implicit return is bad for compiler performance (and sometimes runtime performance) and can adversely affect code readability, so every function which does _not_ return a value should end in a `return` statement. Here, we also introduce a new meaning to the `@nospecialize` macro, and a new macro `@specialize` to reverse its effect. When used without arguments, it applies to all arguments of the parent. In local scope, this means the containing function. In global scope, this means all methods subsequently defined.
1 parent b012ab3 commit 03dfc52

24 files changed

+363
-229
lines changed

NEWS.md

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ Language changes
7878
* Declaring arguments as `x::ANY` to avoid specialization has been replaced
7979
by `@nospecialize x`. ([#22666]).
8080

81+
This can also be used in global scope, to apply to all subsequent method definitions
82+
in the module (until `@specialize`). ([#28065])
83+
8184
* Keyword argument default values are now evaluated in successive scopes ---
8285
the scope for each expression includes only previous keyword arguments, in
8386
left-to-right order ([#17240]).

base/client.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ function run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_fil
349349
term_env = get(ENV, "TERM", @static Sys.iswindows() ? "" : "dumb")
350350
term = REPL.Terminals.TTYTerminal(term_env, stdin, stdout, stderr)
351351
color_set || (global have_color = REPL.Terminals.hascolor(term))
352-
banner && REPL.banner(term, term)
352+
banner && Base.banner(term)
353353
if term.term_type == "dumb"
354354
active_repl = REPL.BasicREPL(term)
355355
quiet || @warn "Terminal not fully functional"

base/compiler/ssair/show.jl

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

3+
@nospecialize
4+
35
if Pair != Base.Pair
46
import Base: Base, IOContext, string, join, sprint
57
IOContext(io::IO, KV::Pair) = IOContext(io, Base.Pair(KV[1], KV[2]))
@@ -26,7 +28,7 @@ end
2628
print_ssa(io::IO, @nospecialize(val), argnames) = Base.show(io, val)
2729

2830

29-
function print_node(io::IO, idx::Int, @nospecialize(stmt), used, argnames, maxsize; color = true, print_typ=true)
31+
function print_node(io::IO, idx::Int, @nospecialize(stmt), used, argnames, maxsize; color::Bool=true, print_typ::Bool=true)
3032
if idx in used
3133
pad = " "^(maxsize-length(string(idx)))
3234
Base.print(io, "%$idx $pad= ")
@@ -428,3 +430,5 @@ function show_ir(io::IO, code::IRCode, expr_type_printer=default_expr_type_print
428430
println(io)
429431
end
430432
end
433+
434+
@specialize

base/compiler/tfuncs.jl

+10-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
# constants #
55
#############
66

7+
@nospecialize
8+
79
const AbstractEvalConstant = Const
810

911
const _NAMEDTUPLE_NAME = NamedTuple.body.body.name
@@ -345,9 +347,9 @@ add_tfunc(nfields, 1, 1,
345347
end
346348
return Int
347349
end, 0)
348-
add_tfunc(Core._expr, 1, INT_INF, (args...)->Expr, 100)
350+
add_tfunc(Core._expr, 1, INT_INF, (@nospecialize args...)->Expr, 100)
349351
add_tfunc(applicable, 1, INT_INF, (@nospecialize(f), args...)->Bool, 100)
350-
add_tfunc(Core.Intrinsics.arraylen, 1, 1, x->Int, 4)
352+
add_tfunc(Core.Intrinsics.arraylen, 1, 1, @nospecialize(x)->Int, 4)
351353
add_tfunc(arraysize, 2, 2, (@nospecialize(a), @nospecialize(d))->Int, 4)
352354
add_tfunc(pointerref, 3, 3,
353355
function (@nospecialize(a), @nospecialize(i), @nospecialize(align))
@@ -466,7 +468,7 @@ add_tfunc(<:, 2, 2,
466468
return Bool
467469
end, 0)
468470

469-
function const_datatype_getfield_tfunc(sv, fld)
471+
function const_datatype_getfield_tfunc(@nospecialize(sv), @nospecialize(fld))
470472
if (fld == DATATYPE_NAME_FIELDINDEX ||
471473
fld == DATATYPE_PARAMETERS_FIELDINDEX ||
472474
fld == DATATYPE_TYPES_FIELDINDEX ||
@@ -980,7 +982,7 @@ function tuple_tfunc(@nospecialize(argtype))
980982
return argtype
981983
end
982984

983-
function array_builtin_common_nothrow(argtypes, first_idx_idx)
985+
function array_builtin_common_nothrow(argtypes::Array{Any,1}, first_idx_idx::Int)
984986
length(argtypes) >= 4 || return false
985987
(argtypes[1] Bool && argtypes[2] Array) || return false
986988
for i = first_idx_idx:length(argtypes)
@@ -1052,7 +1054,7 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1},
10521054
return tuple_tfunc(argtypes_to_type(argtypes))
10531055
end
10541056
end
1055-
return Const(tuple(anymap(a->a.val, argtypes)...))
1057+
return Const(tuple(anymap(a::Const -> a.val, argtypes)...))
10561058
elseif f === svec
10571059
return SimpleVector
10581060
elseif f === arrayset
@@ -1111,7 +1113,7 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1},
11111113
end
11121114
if isa(f, IntrinsicFunction)
11131115
if is_pure_intrinsic_infer(f) && _all(@nospecialize(a) -> isa(a, Const), argtypes)
1114-
argvals = anymap(a -> a.val, argtypes)
1116+
argvals = anymap(a::Const -> a.val, argtypes)
11151117
try
11161118
return Const(f(argvals...))
11171119
catch
@@ -1193,3 +1195,5 @@ function typename_static(@nospecialize(t))
11931195
t = unwrap_unionall(widenconst(t))
11941196
return isType(t) ? _typename(t.parameters[1]) : Core.TypeName
11951197
end
1198+
1199+
@specialize

base/docs/Docs.jl

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ information.
1111
"""
1212
module Docs
1313

14+
@nospecialize # don't specialize on any arguments of the methods declared herein
15+
1416
"""
1517
# Documentation
1618

base/docs/basedocs.jl

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
module BaseDocs
44

5+
@nospecialize # don't specialize on any arguments of the methods declared herein
6+
57
struct Keyword
6-
name :: Symbol
8+
name::Symbol
9+
end
10+
macro kw_str(text)
11+
return Keyword(Symbol(text))
712
end
8-
macro kw_str(text) Keyword(Symbol(text)) end
913

1014
"""
1115
**Welcome to Julia $(string(VERSION)).** The full manual is available at

base/docs/core.jl

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ module CoreDocs
44

55
import ..esc, ..push!, ..getindex, ..unsafe_load, ..Csize_t, ..@nospecialize
66

7+
@nospecialize # don't specialize on any arguments of the methods declared herein
8+
79
function doc!(source::LineNumberNode, mod::Module, str, ex)
8-
@nospecialize str ex
910
push!(DOCS, Core.svec(mod, ex, str, source.file, source.line))
1011
nothing
1112
end
1213
const DOCS = Array{Core.SimpleVector,1}()
1314

14-
isexpr(@nospecialize(x), h::Symbol) = isa(x, Expr) && x.head === h
15+
isexpr(x, h::Symbol) = isa(x, Expr) && x.head === h
1516

1617
lazy_iterpolate(s::AbstractString) = Expr(:call, Core.svec, s)
17-
lazy_iterpolate(@nospecialize x) = isexpr(x, :string) ? Expr(:call, Core.svec, x.args...) : x
18+
lazy_iterpolate(x) = isexpr(x, :string) ? Expr(:call, Core.svec, x.args...) : x
1819

1920
function docm(source::LineNumberNode, mod::Module, str, x)
2021
out = Expr(:call, doc!, QuoteNode(source), mod, lazy_iterpolate(str), QuoteNode(x))

base/essentials.jl

+42-11
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,21 @@ end
3030
@nospecialize
3131
3232
Applied to a function argument name, hints to the compiler that the method
33-
should not be specialized for different types of that argument.
33+
should not be specialized for different types of that argument,
34+
but instead to use precisely the declared type for each argument.
3435
This is only a hint for avoiding excess code generation.
35-
Can be applied to an argument within a formal argument list, or in the
36-
function body.
37-
When applied to an argument, the macro must wrap the entire argument
38-
expression.
36+
Can be applied to an argument within a formal argument list,
37+
or in the function body.
38+
When applied to an argument, the macro must wrap the entire argument expression.
3939
When used in a function body, the macro must occur in statement position and
4040
before any code.
4141
42+
When used without arguments, it applies to all arguments of the parent scope.
43+
In local scope, this means all arguments of the containing function.
44+
In global (top-level) scope, this means all methods subsequently defined in the current module.
45+
46+
Specialization can reset back to the default by using [`@specialize`](@ref).
47+
4248
```julia
4349
function example_function(@nospecialize x)
4450
...
@@ -52,21 +58,46 @@ function example_function(x, y, z)
5258
@nospecialize x y
5359
...
5460
end
61+
62+
@nospecialize
63+
f(y) = [x for x in y]
64+
@specialize
5565
```
5666
"""
57-
macro nospecialize(var, vars...)
58-
if isa(var, Expr) && var.head === :(=)
59-
var.head = :kw
67+
macro nospecialize(vars...)
68+
if nfields(vars) === 1
69+
# in argument position, need to fix `@nospecialize x=v` to `@nospecialize (kw x v)`
70+
var = getfield(vars, 1)
71+
if isa(var, Expr) && var.head === :(=)
72+
var.head = :kw
73+
end
74+
end
75+
return Expr(:meta, :nospecialize, vars...)
76+
end
77+
78+
"""
79+
@specialize
80+
81+
Reset the specialization hint for an argument back to the default.
82+
For details, see [`@specialize`](@ref).
83+
"""
84+
macro specialize(vars...)
85+
if nfields(vars) === 1
86+
# in argument position, need to fix `@specialize x=v` to `@specialize (kw x v)`
87+
var = getfield(vars, 1)
88+
if isa(var, Expr) && var.head === :(=)
89+
var.head = :kw
90+
end
6091
end
61-
Expr(:meta, :nospecialize, var, vars...)
92+
return Expr(:meta, :specialize, vars...)
6293
end
6394

6495
macro _pure_meta()
65-
Expr(:meta, :pure)
96+
return Expr(:meta, :pure)
6697
end
6798
# another version of inlining that propagates an inbounds context
6899
macro _propagate_inbounds_meta()
69-
Expr(:meta, :inline, :propagate_inbounds)
100+
return Expr(:meta, :inline, :propagate_inbounds)
70101
end
71102

72103
"""

base/exports.jl

+1
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ export
970970
@inline,
971971
@noinline,
972972
@nospecialize,
973+
@specialize,
973974
@polly,
974975

975976
@assert,

base/precompile.jl

+15-15
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,9 @@ precompile(Tuple{typeof(Base.getproperty), Core.CodeInfo, Symbol})
247247
precompile(Tuple{typeof(Base.getproperty), Core.LineInfoNode, Symbol})
248248
precompile(Tuple{typeof(Base.getproperty), Core.MethodTable, Symbol})
249249
precompile(Tuple{typeof(Base.getproperty), Method, Symbol})
250-
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}, Symbol})
250+
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.HistoryPrompt, Symbol})
251251
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.ModalInterface, Symbol})
252-
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}, Symbol})
252+
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PrefixHistoryPrompt, Symbol})
253253
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PrefixSearchState, Symbol})
254254
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.Prompt, Symbol})
255255
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PromptState, Symbol})
@@ -440,7 +440,7 @@ precompile(Tuple{typeof(Base.setproperty!), Base.Iterators.Stateful{Tuple{String
440440
precompile(Tuple{typeof(Base.setproperty!), Base.Process, Symbol, Ptr{Nothing}})
441441
precompile(Tuple{typeof(Base.setproperty!), Base.Process, Symbol, Symbol})
442442
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.MIState, Symbol, Symbol})
443-
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}, Symbol, REPL.LineEdit.Prompt})
443+
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixHistoryPrompt, Symbol, REPL.LineEdit.Prompt})
444444
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, Int64})
445445
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, REPL.LineEdit.MIState})
446446
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, REPL.LineEdit.Prompt})
@@ -618,9 +618,9 @@ precompile(Tuple{typeof(Markdown.terminline_string), Base.IOContext{REPL.Termina
618618
precompile(Tuple{typeof(OldPkg.dir)})
619619
precompile(Tuple{typeof(Pkg.REPLMode.create_mode), REPL.LineEditREPL, REPL.LineEdit.Prompt})
620620
precompile(Tuple{typeof(Pkg.REPLMode.repl_init), REPL.LineEditREPL})
621-
precompile(Tuple{typeof(REPL.LineEdit.accept_result), REPL.LineEdit.MIState, REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}})
622-
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
623-
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
621+
precompile(Tuple{typeof(REPL.LineEdit.accept_result), REPL.LineEdit.MIState, REPL.LineEdit.PrefixHistoryPrompt})
622+
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.HistoryPrompt, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
623+
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.PrefixHistoryPrompt, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
624624
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.Prompt, REPL.LineEdit.MIState, REPL.Terminals.TTYTerminal, REPL.Terminals.TTYTerminal})
625625
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.Prompt, REPL.LineEdit.PromptState, REPL.Terminals.TTYTerminal, REPL.Terminals.TTYTerminal})
626626
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.Prompt, REPL.LineEdit.PromptState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
@@ -635,8 +635,8 @@ precompile(Tuple{typeof(REPL.LineEdit.commit_changes), REPL.Terminals.TTYTermina
635635
precompile(Tuple{typeof(REPL.LineEdit.common_prefix), Array{String, 1}})
636636
precompile(Tuple{typeof(REPL.LineEdit.complete_line), REPL.LineEdit.PromptState, Int64})
637637
precompile(Tuple{typeof(REPL.LineEdit.complete_line), REPL.REPLCompletionProvider, REPL.LineEdit.PromptState})
638-
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
639-
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
638+
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.HistoryPrompt, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
639+
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.PrefixHistoryPrompt, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
640640
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.Prompt, REPL.LineEdit.PromptState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
641641
precompile(Tuple{typeof(REPL.LineEdit.deactivate_region), REPL.LineEdit.MIState})
642642
precompile(Tuple{typeof(REPL.LineEdit.deactivate_region), REPL.LineEdit.PromptState})
@@ -650,14 +650,14 @@ precompile(Tuple{typeof(REPL.LineEdit.edit_splice!), REPL.LineEdit.PromptState,
650650
precompile(Tuple{typeof(REPL.LineEdit.eval), Module, Expr})
651651
precompile(Tuple{typeof(REPL.LineEdit.history_next_prefix), REPL.LineEdit.PrefixSearchState, REPL.REPLHistoryProvider, String})
652652
precompile(Tuple{typeof(REPL.LineEdit.history_prev_prefix), REPL.LineEdit.PrefixSearchState, REPL.REPLHistoryProvider, String})
653-
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}})
653+
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.HistoryPrompt})
654654
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.ModalInterface})
655-
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}})
655+
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.PrefixHistoryPrompt})
656656
precompile(Tuple{typeof(REPL.LineEdit.is_region_active), REPL.LineEdit.MIState})
657-
precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}})
658-
precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}})
659-
precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}})
660-
precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}})
657+
precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt})
658+
precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt})
659+
precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt})
660+
precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt})
661661
precompile(Tuple{typeof(REPL.LineEdit.match_input), Base.Dict{Char, Any}, REPL.LineEdit.MIState, Base.GenericIOBuffer{Array{UInt8, 1}}})
662662
precompile(Tuple{typeof(REPL.LineEdit.match_input), Base.Dict{Char, Any}, REPL.LineEdit.MIState, REPL.Terminals.TTYTerminal, Array{Char, 1}, Base.Dict{Char, Any}})
663663
precompile(Tuple{typeof(REPL.LineEdit.match_input), Base.Dict{Char, Any}, REPL.LineEdit.MIState})
@@ -705,7 +705,7 @@ precompile(Tuple{typeof(REPL.Terminals.cmove_col), REPL.Terminals.TTYTerminal, I
705705
precompile(Tuple{typeof(REPL.Terminals.cmove_down), REPL.Terminals.TTYTerminal, Int64})
706706
precompile(Tuple{typeof(REPL.Terminals.hascolor), REPL.Terminals.TTYTerminal})
707707
precompile(Tuple{typeof(REPL.Terminals.width), REPL.Terminals.TTYTerminal})
708-
precompile(Tuple{typeof(REPL.banner), REPL.Terminals.TTYTerminal, REPL.Terminals.TTYTerminal})
708+
precompile(Tuple{typeof(Base.banner), REPL.Terminals.TTYTerminal})
709709
precompile(Tuple{typeof(REPL.ends_with_semicolon), String})
710710
precompile(Tuple{typeof(REPL.eval), Module, Expr})
711711
precompile(Tuple{typeof(REPL.eval), Module, String})

doc/src/base/base.md

+1
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ Base.@boundscheck
213213
Base.@inline
214214
Base.@noinline
215215
Base.@nospecialize
216+
Base.@specialize
216217
Base.gensym
217218
Base.@gensym
218219
Base.@goto

src/ast.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@ jl_sym_t *inert_sym; jl_sym_t *vararg_sym;
6060
jl_sym_t *unused_sym; jl_sym_t *static_parameter_sym;
6161
jl_sym_t *inline_sym; jl_sym_t *noinline_sym;
6262
jl_sym_t *polly_sym;
63-
jl_sym_t *propagate_inbounds_sym; jl_sym_t *generated_sym;
64-
jl_sym_t *generated_only_sym;
65-
jl_sym_t *isdefined_sym; jl_sym_t *nospecialize_sym;
66-
jl_sym_t *macrocall_sym; jl_sym_t *colon_sym;
67-
jl_sym_t *hygienicscope_sym;
68-
jl_sym_t *escape_sym;
63+
jl_sym_t *propagate_inbounds_sym;
64+
jl_sym_t *generated_sym; jl_sym_t *generated_only_sym;
65+
jl_sym_t *isdefined_sym;
66+
jl_sym_t *specialize_sym; jl_sym_t *nospecialize_sym;
67+
jl_sym_t *macrocall_sym;
68+
jl_sym_t *colon_sym;
69+
jl_sym_t *hygienicscope_sym; jl_sym_t *escape_sym;
6970
jl_sym_t *gc_preserve_begin_sym; jl_sym_t *gc_preserve_end_sym;
7071
jl_sym_t *throw_undef_if_not_sym; jl_sym_t *getfield_undefref_sym;
7172

@@ -384,6 +385,7 @@ void jl_init_frontend(void)
384385
propagate_inbounds_sym = jl_symbol("propagate_inbounds");
385386
isdefined_sym = jl_symbol("isdefined");
386387
nospecialize_sym = jl_symbol("nospecialize");
388+
specialize_sym = jl_symbol("specialize");
387389
macrocall_sym = jl_symbol("macrocall");
388390
escape_sym = jl_symbol("escape");
389391
hygienicscope_sym = jl_symbol("hygienic-scope");

src/ast.scm

+1-1
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@
465465

466466
(define (nospecialize-meta? e (one #f))
467467
(and (if one (length= e 3) (length> e 2))
468-
(eq? (car e) 'meta) (eq? (cadr e) 'nospecialize)))
468+
(eq? (car e) 'meta) (memq (cadr e) '(nospecialize specialize))))
469469

470470
(define (if-generated? e)
471471
(and (length= e 4) (eq? (car e) 'if) (equal? (cadr e) '(generated))))

src/dump.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ static void jl_serialize_module(jl_serializer_state *s, jl_module_t *m)
443443
write_uint64(s->s, m->uuid.lo);
444444
write_uint64(s->s, m->build_id);
445445
write_int32(s->s, m->counter);
446+
write_int32(s->s, m->nospecialize);
446447
}
447448

448449
static int is_ast_node(jl_value_t *v)
@@ -1781,8 +1782,9 @@ static jl_value_t *jl_deserialize_value_module(jl_serializer_state *s)
17811782
m->uuid.hi = read_uint64(s->s);
17821783
m->uuid.lo = read_uint64(s->s);
17831784
m->build_id = read_uint64(s->s);
1784-
m->primary_world = jl_world_counter;
17851785
m->counter = read_int32(s->s);
1786+
m->nospecialize = read_int32(s->s);
1787+
m->primary_world = jl_world_counter;
17861788
return (jl_value_t*)m;
17871789
}
17881790

0 commit comments

Comments
 (0)