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

performance: mark REPL and Doc code as non-specializeable #28065

Merged
merged 1 commit into from
Jul 20, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ Language changes
* Declaring arguments as `x::ANY` to avoid specialization has been replaced
by `@nospecialize x`. ([#22666]).

This can also be used in global scope, to apply to all subsequent method definitions
in the module (until `@specialize`). ([#28065])

* Keyword argument default values are now evaluated in successive scopes ---
the scope for each expression includes only previous keyword arguments, in
left-to-right order ([#17240]).
Expand Down
2 changes: 1 addition & 1 deletion base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ function run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_fil
term_env = get(ENV, "TERM", @static Sys.iswindows() ? "" : "dumb")
term = REPL.Terminals.TTYTerminal(term_env, stdin, stdout, stderr)
color_set || (global have_color = REPL.Terminals.hascolor(term))
banner && REPL.banner(term, term)
banner && Base.banner(term)
if term.term_type == "dumb"
active_repl = REPL.BasicREPL(term)
quiet || @warn "Terminal not fully functional"
Expand Down
6 changes: 5 additions & 1 deletion base/compiler/ssair/show.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

@nospecialize

if Pair != Base.Pair
import Base: Base, IOContext, string, join, sprint
IOContext(io::IO, KV::Pair) = IOContext(io, Base.Pair(KV[1], KV[2]))
Expand All @@ -26,7 +28,7 @@ end
print_ssa(io::IO, @nospecialize(val), argnames) = Base.show(io, val)


function print_node(io::IO, idx::Int, @nospecialize(stmt), used, argnames, maxsize; color = true, print_typ=true)
function print_node(io::IO, idx::Int, @nospecialize(stmt), used, argnames, maxsize; color::Bool=true, print_typ::Bool=true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the @nospecialize be removed here since it is in a @nospecialize true block?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could, but I like the reminders that this code will run very slowly if you aren't careful

if idx in used
pad = " "^(maxsize-length(string(idx)))
Base.print(io, "%$idx $pad= ")
Expand Down Expand Up @@ -428,3 +430,5 @@ function show_ir(io::IO, code::IRCode, expr_type_printer=default_expr_type_print
println(io)
end
end

@specialize
16 changes: 10 additions & 6 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# constants #
#############

@nospecialize

const AbstractEvalConstant = Const

const _NAMEDTUPLE_NAME = NamedTuple.body.body.name
Expand Down Expand Up @@ -345,9 +347,9 @@ add_tfunc(nfields, 1, 1,
end
return Int
end, 0)
add_tfunc(Core._expr, 1, INT_INF, (args...)->Expr, 100)
add_tfunc(Core._expr, 1, INT_INF, (@nospecialize args...)->Expr, 100)
add_tfunc(applicable, 1, INT_INF, (@nospecialize(f), args...)->Bool, 100)
add_tfunc(Core.Intrinsics.arraylen, 1, 1, x->Int, 4)
add_tfunc(Core.Intrinsics.arraylen, 1, 1, @nospecialize(x)->Int, 4)
add_tfunc(arraysize, 2, 2, (@nospecialize(a), @nospecialize(d))->Int, 4)
add_tfunc(pointerref, 3, 3,
function (@nospecialize(a), @nospecialize(i), @nospecialize(align))
Expand Down Expand Up @@ -466,7 +468,7 @@ add_tfunc(<:, 2, 2,
return Bool
end, 0)

function const_datatype_getfield_tfunc(sv, fld)
function const_datatype_getfield_tfunc(@nospecialize(sv), @nospecialize(fld))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fld should be an Int.

if (fld == DATATYPE_NAME_FIELDINDEX ||
fld == DATATYPE_PARAMETERS_FIELDINDEX ||
fld == DATATYPE_TYPES_FIELDINDEX ||
Expand Down Expand Up @@ -980,7 +982,7 @@ function tuple_tfunc(@nospecialize(argtype))
return argtype
end

function array_builtin_common_nothrow(argtypes, first_idx_idx)
function array_builtin_common_nothrow(argtypes::Array{Any,1}, first_idx_idx::Int)
length(argtypes) >= 4 || return false
(argtypes[1] ⊑ Bool && argtypes[2] ⊑ Array) || return false
for i = first_idx_idx:length(argtypes)
Expand Down Expand Up @@ -1052,7 +1054,7 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1},
return tuple_tfunc(argtypes_to_type(argtypes))
end
end
return Const(tuple(anymap(a->a.val, argtypes)...))
return Const(tuple(anymap(a::Const -> a.val, argtypes)...))
elseif f === svec
return SimpleVector
elseif f === arrayset
Expand Down Expand Up @@ -1111,7 +1113,7 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1},
end
if isa(f, IntrinsicFunction)
if is_pure_intrinsic_infer(f) && _all(@nospecialize(a) -> isa(a, Const), argtypes)
argvals = anymap(a -> a.val, argtypes)
argvals = anymap(a::Const -> a.val, argtypes)
try
return Const(f(argvals...))
catch
Expand Down Expand Up @@ -1193,3 +1195,5 @@ function typename_static(@nospecialize(t))
t = unwrap_unionall(widenconst(t))
return isType(t) ? _typename(t.parameters[1]) : Core.TypeName
end

@specialize
2 changes: 2 additions & 0 deletions base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ information.
"""
module Docs

@nospecialize # don't specialize on any arguments of the methods declared herein

"""
# Documentation

Expand Down
8 changes: 6 additions & 2 deletions base/docs/basedocs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

module BaseDocs

@nospecialize # don't specialize on any arguments of the methods declared herein

struct Keyword
name :: Symbol
name::Symbol
end
macro kw_str(text)
return Keyword(Symbol(text))
end
macro kw_str(text) Keyword(Symbol(text)) end

"""
**Welcome to Julia $(string(VERSION)).** The full manual is available at
Expand Down
7 changes: 4 additions & 3 deletions base/docs/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ module CoreDocs

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

@nospecialize # don't specialize on any arguments of the methods declared herein

function doc!(source::LineNumberNode, mod::Module, str, ex)
@nospecialize str ex
push!(DOCS, Core.svec(mod, ex, str, source.file, source.line))
nothing
end
const DOCS = Array{Core.SimpleVector,1}()

isexpr(@nospecialize(x), h::Symbol) = isa(x, Expr) && x.head === h
isexpr(x, h::Symbol) = isa(x, Expr) && x.head === h

lazy_iterpolate(s::AbstractString) = Expr(:call, Core.svec, s)
lazy_iterpolate(@nospecialize x) = isexpr(x, :string) ? Expr(:call, Core.svec, x.args...) : x
lazy_iterpolate(x) = isexpr(x, :string) ? Expr(:call, Core.svec, x.args...) : x

function docm(source::LineNumberNode, mod::Module, str, x)
out = Expr(:call, doc!, QuoteNode(source), mod, lazy_iterpolate(str), QuoteNode(x))
Expand Down
53 changes: 42 additions & 11 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,21 @@ end
@nospecialize

Applied to a function argument name, hints to the compiler that the method
should not be specialized for different types of that argument.
should not be specialized for different types of that argument,
but instead to use precisely the declared type for each argument.
This is only a hint for avoiding excess code generation.
Can be applied to an argument within a formal argument list, or in the
function body.
When applied to an argument, the macro must wrap the entire argument
expression.
Can be applied to an argument within a formal argument list,
or in the function body.
When applied to an argument, the macro must wrap the entire argument expression.
When used in a function body, the macro must occur in statement position and
before any code.

When used without arguments, it applies to all arguments of the parent scope.
In local scope, this means all arguments of the containing function.
In global (top-level) scope, this means all methods subsequently defined in the current module.
Copy link
Member

@stevengj stevengj Jul 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems more natural to me to use a syntax like

@nospecialize foo(...) = ... # applies to all arguments
@nospecialize begin ... end # applies to all methods defined in this block
@nospecialize module Foo ... end # applies to all methods in module Foo

rather than acting like an imperative side-effect, and to have a @nospecialize false begin ... end antonym.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, all of those can be added later to the macro. They'd just be syntax transforms to one of these forms, since this form – as an imperative side-effect – represents where that information needs to be present in the processing order (since method declaration is itself also imperative).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, @nospecialize false is double negation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does seem clearer for the low-level control to be @specialize! true|false defaulting to true to avoid the double negative. Then @nospecialize block forms like @stevengj outlined can be built on top of that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for the module-level form @specialize is better, but I'd keep @nospecialize as well since it's much more convenient when annotating a single argument. Then we could potentially use those instead of the true/false argument.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:

@nospecialize [begin]
define() = functions
@nospecialize [end]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can’t tell if you’re trolling


Specialization can reset back to the default by using [`@specialize`](@ref).

```julia
function example_function(@nospecialize x)
...
Expand All @@ -52,21 +58,46 @@ function example_function(x, y, z)
@nospecialize x y
...
end

@nospecialize
f(y) = [x for x in y]
@specialize
```
"""
macro nospecialize(var, vars...)
if isa(var, Expr) && var.head === :(=)
var.head = :kw
macro nospecialize(vars...)
if nfields(vars) === 1
# in argument position, need to fix `@nospecialize x=v` to `@nospecialize (kw x v)`
var = getfield(vars, 1)
if isa(var, Expr) && var.head === :(=)
var.head = :kw
end
end
return Expr(:meta, :nospecialize, vars...)
end

"""
@specialize

Reset the specialization hint for an argument back to the default.
For details, see [`@specialize`](@ref).
"""
macro specialize(vars...)
if nfields(vars) === 1
# in argument position, need to fix `@specialize x=v` to `@specialize (kw x v)`
var = getfield(vars, 1)
if isa(var, Expr) && var.head === :(=)
var.head = :kw
end
end
Expr(:meta, :nospecialize, var, vars...)
return Expr(:meta, :specialize, vars...)
end

macro _pure_meta()
Expr(:meta, :pure)
return Expr(:meta, :pure)
end
# another version of inlining that propagates an inbounds context
macro _propagate_inbounds_meta()
Expr(:meta, :inline, :propagate_inbounds)
return Expr(:meta, :inline, :propagate_inbounds)
end

"""
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,7 @@ export
@inline,
@noinline,
@nospecialize,
@specialize,
@polly,

@assert,
Expand Down
30 changes: 15 additions & 15 deletions base/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ precompile(Tuple{typeof(Base.getproperty), Core.CodeInfo, Symbol})
precompile(Tuple{typeof(Base.getproperty), Core.LineInfoNode, Symbol})
precompile(Tuple{typeof(Base.getproperty), Core.MethodTable, Symbol})
precompile(Tuple{typeof(Base.getproperty), Method, Symbol})
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}, Symbol})
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.HistoryPrompt, Symbol})
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.ModalInterface, Symbol})
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}, Symbol})
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PrefixHistoryPrompt, Symbol})
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PrefixSearchState, Symbol})
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.Prompt, Symbol})
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.PromptState, Symbol})
Expand Down Expand Up @@ -440,7 +440,7 @@ precompile(Tuple{typeof(Base.setproperty!), Base.Iterators.Stateful{Tuple{String
precompile(Tuple{typeof(Base.setproperty!), Base.Process, Symbol, Ptr{Nothing}})
precompile(Tuple{typeof(Base.setproperty!), Base.Process, Symbol, Symbol})
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.MIState, Symbol, Symbol})
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}, Symbol, REPL.LineEdit.Prompt})
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixHistoryPrompt, Symbol, REPL.LineEdit.Prompt})
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, Int64})
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, REPL.LineEdit.MIState})
precompile(Tuple{typeof(Base.setproperty!), REPL.LineEdit.PrefixSearchState, Symbol, REPL.LineEdit.Prompt})
Expand Down Expand Up @@ -618,9 +618,9 @@ precompile(Tuple{typeof(Markdown.terminline_string), Base.IOContext{REPL.Termina
precompile(Tuple{typeof(OldPkg.dir)})
precompile(Tuple{typeof(Pkg.REPLMode.create_mode), REPL.LineEditREPL, REPL.LineEdit.Prompt})
precompile(Tuple{typeof(Pkg.REPLMode.repl_init), REPL.LineEditREPL})
precompile(Tuple{typeof(REPL.LineEdit.accept_result), REPL.LineEdit.MIState, REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}})
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.accept_result), REPL.LineEdit.MIState, REPL.LineEdit.PrefixHistoryPrompt})
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.HistoryPrompt, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.PrefixHistoryPrompt, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.Prompt, REPL.LineEdit.MIState, REPL.Terminals.TTYTerminal, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.Prompt, REPL.LineEdit.PromptState, REPL.Terminals.TTYTerminal, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.Prompt, REPL.LineEdit.PromptState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
Expand All @@ -635,8 +635,8 @@ precompile(Tuple{typeof(REPL.LineEdit.commit_changes), REPL.Terminals.TTYTermina
precompile(Tuple{typeof(REPL.LineEdit.common_prefix), Array{String, 1}})
precompile(Tuple{typeof(REPL.LineEdit.complete_line), REPL.LineEdit.PromptState, Int64})
precompile(Tuple{typeof(REPL.LineEdit.complete_line), REPL.REPLCompletionProvider, REPL.LineEdit.PromptState})
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.HistoryPrompt, REPL.LineEdit.SearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.PrefixHistoryPrompt, REPL.LineEdit.PrefixSearchState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.deactivate), REPL.LineEdit.Prompt, REPL.LineEdit.PromptState, REPL.Terminals.TerminalBuffer, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.LineEdit.deactivate_region), REPL.LineEdit.MIState})
precompile(Tuple{typeof(REPL.LineEdit.deactivate_region), REPL.LineEdit.PromptState})
Expand All @@ -650,14 +650,14 @@ precompile(Tuple{typeof(REPL.LineEdit.edit_splice!), REPL.LineEdit.PromptState,
precompile(Tuple{typeof(REPL.LineEdit.eval), Module, Expr})
precompile(Tuple{typeof(REPL.LineEdit.history_next_prefix), REPL.LineEdit.PrefixSearchState, REPL.REPLHistoryProvider, String})
precompile(Tuple{typeof(REPL.LineEdit.history_prev_prefix), REPL.LineEdit.PrefixSearchState, REPL.REPLHistoryProvider, String})
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}})
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.HistoryPrompt})
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.ModalInterface})
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}})
precompile(Tuple{typeof(REPL.LineEdit.init_state), REPL.Terminals.TTYTerminal, REPL.LineEdit.PrefixHistoryPrompt})
precompile(Tuple{typeof(REPL.LineEdit.is_region_active), REPL.LineEdit.MIState})
precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}})
precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}})
precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt{REPL.REPLHistoryProvider}})
precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt{REPL.REPLHistoryProvider}})
precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt})
precompile(Tuple{typeof(REPL.LineEdit.keymap), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt})
precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.PrefixSearchState, REPL.LineEdit.PrefixHistoryPrompt})
precompile(Tuple{typeof(REPL.LineEdit.keymap_data), REPL.LineEdit.SearchState, REPL.LineEdit.HistoryPrompt})
precompile(Tuple{typeof(REPL.LineEdit.match_input), Base.Dict{Char, Any}, REPL.LineEdit.MIState, Base.GenericIOBuffer{Array{UInt8, 1}}})
precompile(Tuple{typeof(REPL.LineEdit.match_input), Base.Dict{Char, Any}, REPL.LineEdit.MIState, REPL.Terminals.TTYTerminal, Array{Char, 1}, Base.Dict{Char, Any}})
precompile(Tuple{typeof(REPL.LineEdit.match_input), Base.Dict{Char, Any}, REPL.LineEdit.MIState})
Expand Down Expand Up @@ -705,7 +705,7 @@ precompile(Tuple{typeof(REPL.Terminals.cmove_col), REPL.Terminals.TTYTerminal, I
precompile(Tuple{typeof(REPL.Terminals.cmove_down), REPL.Terminals.TTYTerminal, Int64})
precompile(Tuple{typeof(REPL.Terminals.hascolor), REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.Terminals.width), REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.banner), REPL.Terminals.TTYTerminal, REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(Base.banner), REPL.Terminals.TTYTerminal})
precompile(Tuple{typeof(REPL.ends_with_semicolon), String})
precompile(Tuple{typeof(REPL.eval), Module, Expr})
precompile(Tuple{typeof(REPL.eval), Module, String})
Expand Down
1 change: 1 addition & 0 deletions doc/src/base/base.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ Base.@boundscheck
Base.@inline
Base.@noinline
Base.@nospecialize
Base.@specialize
Base.gensym
Base.@gensym
Base.@goto
Expand Down
14 changes: 8 additions & 6 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@ jl_sym_t *inert_sym; jl_sym_t *vararg_sym;
jl_sym_t *unused_sym; jl_sym_t *static_parameter_sym;
jl_sym_t *inline_sym; jl_sym_t *noinline_sym;
jl_sym_t *polly_sym;
jl_sym_t *propagate_inbounds_sym; jl_sym_t *generated_sym;
jl_sym_t *generated_only_sym;
jl_sym_t *isdefined_sym; jl_sym_t *nospecialize_sym;
jl_sym_t *macrocall_sym; jl_sym_t *colon_sym;
jl_sym_t *hygienicscope_sym;
jl_sym_t *escape_sym;
jl_sym_t *propagate_inbounds_sym;
jl_sym_t *generated_sym; jl_sym_t *generated_only_sym;
jl_sym_t *isdefined_sym;
jl_sym_t *specialize_sym; jl_sym_t *nospecialize_sym;
jl_sym_t *macrocall_sym;
jl_sym_t *colon_sym;
jl_sym_t *hygienicscope_sym; jl_sym_t *escape_sym;
jl_sym_t *gc_preserve_begin_sym; jl_sym_t *gc_preserve_end_sym;
jl_sym_t *throw_undef_if_not_sym; jl_sym_t *getfield_undefref_sym;

Expand Down Expand Up @@ -384,6 +385,7 @@ void jl_init_frontend(void)
propagate_inbounds_sym = jl_symbol("propagate_inbounds");
isdefined_sym = jl_symbol("isdefined");
nospecialize_sym = jl_symbol("nospecialize");
specialize_sym = jl_symbol("specialize");
macrocall_sym = jl_symbol("macrocall");
escape_sym = jl_symbol("escape");
hygienicscope_sym = jl_symbol("hygienic-scope");
Expand Down
2 changes: 1 addition & 1 deletion src/ast.scm
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@

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

(define (if-generated? e)
(and (length= e 4) (eq? (car e) 'if) (equal? (cadr e) '(generated))))
Expand Down
4 changes: 3 additions & 1 deletion src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ static void jl_serialize_module(jl_serializer_state *s, jl_module_t *m)
write_uint64(s->s, m->uuid.lo);
write_uint64(s->s, m->build_id);
write_int32(s->s, m->counter);
write_int32(s->s, m->nospecialize);
}

static int is_ast_node(jl_value_t *v)
Expand Down Expand Up @@ -1781,8 +1782,9 @@ static jl_value_t *jl_deserialize_value_module(jl_serializer_state *s)
m->uuid.hi = read_uint64(s->s);
m->uuid.lo = read_uint64(s->s);
m->build_id = read_uint64(s->s);
m->primary_world = jl_world_counter;
m->counter = read_int32(s->s);
m->nospecialize = read_int32(s->s);
m->primary_world = jl_world_counter;
return (jl_value_t*)m;
}

Expand Down
Loading