Skip to content

Commit

Permalink
Stylistic updates to the devdocs for consistency (JuliaLang#21464)
Browse files Browse the repository at this point in the history
  • Loading branch information
ararslan authored Apr 22, 2017
1 parent 525f996 commit 56d976a
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 187 deletions.
2 changes: 1 addition & 1 deletion doc/src/devdocs/ast.md
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ parses as:
Type definition:

```julia
type Foo{T<:S}
mutable struct Foo{T<:S}
x::T
end
```
Expand Down
2 changes: 1 addition & 1 deletion doc/src/devdocs/cartesian.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Starting in Julia 0.4-pre, the recommended approach is to use a `@generated func
an example:

```julia
@generated function mysum{T,N}(A::Array{T,N})
@generated function mysum(A::Array{T,N}) where {T,N}
quote
s = zero(T)
@nloops $N i A begin
Expand Down
8 changes: 2 additions & 6 deletions doc/src/devdocs/compiler.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
# High-level Overview of the Native-Code Generation Process


<placeholder>


## Representation of Pointers

When emitting code to an object file, pointers will be emitted as relocations.
Expand All @@ -24,10 +20,10 @@ Function pointers are handled similarly.
They are stored as values in a large `fvals` table.
Like globals, this allows the deserializer to reference them by index.

Note that extern functions are handled separately,
Note that `extern` functions are handled separately,
with names, via the usual symbol resolution mechanism in the linker.

Note too that ccall functions are also handled separately,
Note too that `ccall` functions are also handled separately,
via a manual GOT and Procedure Linkage Table (PLT).


Expand Down
4 changes: 2 additions & 2 deletions doc/src/devdocs/debuggingtips.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ process)

## Mozilla's Record and Replay Framework (rr)

Julia now works out of the box with [rr,](http://rr-project.org/) the lightweight recording and
Julia now works out of the box with [rr](http://rr-project.org/), the lightweight recording and
deterministic debugging framework from Mozilla. This allows you to replay the trace of an execution
deterministically. The replayed execution's address spaces, register contents, syscall data etc
are exactly the same in every run.

A recent version of `rr` (3.1.0 or higher) is required.
A recent version of rr (3.1.0 or higher) is required.
30 changes: 15 additions & 15 deletions doc/src/devdocs/eval.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
One of the hardest parts about learning how the Julia Language runs code is learning how all of
the pieces work together to execute a block of code.

Each chunk of code typically makes a trip through many esoteric acronyms such as (in no particular
order), `flisp`, `AST`, `C++`, `LLVM`, `eval`, `typeinf`, `macroexpand`, `sysimg` (or `system image`),
`bootstrapping`, `compile`, `parse`, `execute`, `JIT`, `interpret`, `box`, `unbox`, `intrinsic function`,
`primitive function` before turning into the desired result (hopefully).
Each chunk of code typically makes a trip through many steps with potentially unfamiliar names,
such as (in no particular order): flisp, AST, C++, LLVM, `eval`, `typeinf`, `macroexpand`, sysimg
(or system image), bootstrapping, compile, parse, execute, JIT, interpret, box, unbox, intrinsic
function, and primitive function, before turning into the desired result (hopefully).

!!! sidebar "Definitions"
* REPL
Expand All @@ -25,36 +25,36 @@ The 10,000 foot view of the whole process is as follows:
1. The user starts `julia`.
2. The C function `main()` from `ui/repl.c` gets called. This function processes the command line
arguments, filling in the `jl_options` struct and setting the variable `ARGS`. It then initializes
Julia (by calling [julia_init in task.c](https://github.com/JuliaLang/julia/blob/master/src/task.c),
Julia (by calling [`julia_init` in task.c](https://github.com/JuliaLang/julia/blob/master/src/task.c),
which may load a previously compiled [sysimg](@ref dev-sysimg)). Finally, it passes off control to Julia
by calling [Base._start()](https://github.com/JuliaLang/julia/blob/master/base/client.jl).
by calling [`Base._start()`](https://github.com/JuliaLang/julia/blob/master/base/client.jl).
3. When `_start()` takes over control, the subsequent sequence of commands depends on the command
line arguments given. For example, if a filename was supplied, it will proceed to execute that
file. Otherwise, it will start an interactive REPL.
4. Skipping the details about how the REPL interacts with the user, let's just say the program ends
up with a block of code that it wants to run.
5. If the block of code to run is in a file, [jl_load(char *filename)](https://github.com/JuliaLang/julia/blob/master/src/toplevel.c)
5. If the block of code to run is in a file, [`jl_load(char *filename)`](https://github.com/JuliaLang/julia/blob/master/src/toplevel.c)
gets invoked to load the file and [parse](@ref dev-parsing) it. Each fragment of code is then passed to `eval`
to execute.
6. Each fragment of code (or AST), is handed off to [`eval()`](@ref) to turn into results.
7. [`eval()`](@ref) takes each code fragment and tries to run it in [jl_toplevel_eval_flex()](https://github.com/JuliaLang/julia/blob/master/src/toplevel.c).
7. [`eval()`](@ref) takes each code fragment and tries to run it in [`jl_toplevel_eval_flex()`](https://github.com/JuliaLang/julia/blob/master/src/toplevel.c).
8. `jl_toplevel_eval_flex()` decides whether the code is a "toplevel" action (such as `using` or
`module`), which would be invalid inside a function. If so, it passes off the code to the toplevel
interpreter.
9. `jl_toplevel_eval_flex()` then [expands](@ref dev-macro-expansion) the code to eliminate any macros and to "lower"
the AST to make it simpler to execute.
10. `jl_toplevel_eval_flex()` then uses some simple heuristics to decide whether to JIT compiler the
AST or to interpret it directly.
11. The bulk of the work to interpret code is handled by [eval in interpreter.c](https://github.com/JuliaLang/julia/blob/master/src/interpreter.c).
11. The bulk of the work to interpret code is handled by [`eval` in interpreter.c](https://github.com/JuliaLang/julia/blob/master/src/interpreter.c).
12. If instead, the code is compiled, the bulk of the work is handled by `codegen.cpp`. Whenever a
Julia function is called for the first time with a given set of argument types, [type inference](@ref dev-type-inference)
will be run on that function. This information is used by the [codegen](@ref dev-codegen) step to generate
faster code.
13. Eventually, the user quits the REPL, or the end of the program is reached, and the `_start()`
method returns.
14. Just before exiting, `main()` calls [jl_atexit_hook(exit_code)](https://github.com/JuliaLang/julia/blob/master/src/init.c).
14. Just before exiting, `main()` calls [`jl_atexit_hook(exit_code)`](https://github.com/JuliaLang/julia/blob/master/src/init.c).
This calls `Base._atexit()` (which calls any functions registered to [`atexit()`](@ref) inside
Julia). Then it calls [jl_gc_run_all_finalizers()](https://github.com/JuliaLang/julia/blob/master/src/gc.c).
Julia). Then it calls [`jl_gc_run_all_finalizers()`](https://github.com/JuliaLang/julia/blob/master/src/gc.c).
Finally, it gracefully cleans up all `libuv` handles and waits for them to flush and close.

## [Parsing](@id dev-parsing)
Expand Down Expand Up @@ -103,7 +103,7 @@ Type inference may also include other steps such as constant propagation and inl
* C++

The programming language that LLVM is implemented in, which means that codegen is also implemented
in this language. The rest of Julia's library is implemented in C, in part because it's smaller
in this language. The rest of Julia's library is implemented in C, in part because its smaller
feature set makes it more usable as a cross-language interface layer.
* box

Expand Down Expand Up @@ -135,7 +135,7 @@ Type inference may also include other steps such as constant propagation and inl

Codegen is the process of turning a Julia AST into native machine code.

The JIT environment is initialized by an early call to [jl_init_codegen in codegen.cpp](https://github.com/JuliaLang/julia/blob/master/src/codegen.cpp).
The JIT environment is initialized by an early call to [`jl_init_codegen` in codegen.cpp](https://github.com/JuliaLang/julia/blob/master/src/codegen.cpp).

On demand, a Julia method is converted into a native function by the function `emit_function(jl_method_instance_t*)`.
(note, when using the MCJIT (in LLVM v3.4+), each function must be JIT into a new module.) This
Expand All @@ -161,7 +161,7 @@ Other parts of codegen are handled by various helper files:
!!! sidebar "Bootstrapping"
The process of creating a new system image is called "bootstrapping".

The etymology of this word comes from the phrase "pulling one's self up by the bootstraps", and
The etymology of this word comes from the phrase "pulling oneself up by the bootstraps", and
refers to the idea of starting from a very limited set of available functions and definitions
and ending with the creation of a full-featured environment.

Expand All @@ -172,7 +172,7 @@ with Julia is one such system image, generated by executing the file [sysimg.jl]
and serializing the resulting environment (including Types, Functions, Modules, and all other
defined values) into a file. Therefore, it contains a frozen version of the `Main`, `Core`, and
`Base` modules (and whatever else was in the environment at the end of bootstrapping). This serializer/deserializer
is implemented by [jl_save_system_image/jl_restore_system_image in dump.c](https://github.com/JuliaLang/julia/blob/master/src/dump.c).
is implemented by [`jl_save_system_image`/`jl_restore_system_image` in dump.c](https://github.com/JuliaLang/julia/blob/master/src/dump.c).

If there is no sysimg file (`jl_options.image_file == NULL`), this also implies that `--build`
was given on the command line, so the final result should be a new sysimg file. During Julia initialization,
Expand Down
16 changes: 8 additions & 8 deletions doc/src/devdocs/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ of the argument structure.
For example, the following function for performing a call accepts just an `args` pointer, so the
first element of the args array will be the function to call:

```
```c
jl_value_t *jl_apply(jl_value_t **args, uint32_t nargs)
```
This entry point for the same functionality accepts the function separately, so the `args` array
does not contain the function:
```
```c
jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs);
```

Expand Down Expand Up @@ -110,7 +110,7 @@ a method table via special arrangement.
The "builtin" functions, defined in the `Core` module, are:
```
is typeof sizeof issubtype isa typeassert throw tuple getfield setfield! fieldtype
=== typeof sizeof issubtype isa typeassert throw tuple getfield setfield! fieldtype
nfields isdefined arrayref arrayset arraysize applicable invoke apply_type _apply
_expr svec
```
Expand All @@ -119,7 +119,7 @@ These are all singleton objects whose types are subtypes of `Builtin`, which is
`Function`. Their purpose is to expose entry points in the run time that use the "jlcall" calling
convention:
```
```c
jl_value_t *(jl_value_t*, jl_value_t**, uint32_t)
```
Expand Down Expand Up @@ -152,7 +152,7 @@ actually produces *three* method definitions. The first is a function that accep
(including keywords) as positional arguments, and includes the code for the method body. It has
an auto-generated name:
```
```julia
function #circle#1(color, fill::Bool, options, circle, center, radius)
# draw
end
Expand Down Expand Up @@ -268,11 +268,11 @@ filtering definitions from "replaced modules" out of method tables and caches be
system image. A "replaced module" is one that satisfies the condition `m != jl_get_global(m->parent, m->name)`
-- in other words, some newer module has taken its name and place.
Another type inference worst case was triggered by the following code from the QuadGK.jl package,
Another type inference worst case was triggered by the following code from the [QuadGK.jl package](https://github.com/JuliaMath/QuadGK.jl),
formerly part of Base:
```julia
function do_quadgk{Tw}(f, s, n, ::Type{Tw}, abstol, reltol, maxevals, nrm)
function do_quadgk(f, s, n, ::Type{Tw}, abstol, reltol, maxevals, nrm) where Tw
if eltype(s) <: Real # check for infinite or semi-infinite intervals
s1 = s[1]; s2 = s[end]; inf1 = isinf(s1); inf2 = isinf(s2)
if inf1 || inf2
Expand Down Expand Up @@ -300,5 +300,5 @@ function do_quadgk{Tw}(f, s, n, ::Type{Tw}, abstol, reltol, maxevals, nrm)
This code has a 3-way tail recursion, where each call wraps the current function argument `f`
in a different new closure. Inference must consider 3^n (where n is the call depth) possible signatures.
This blows up way too quickly, so logic was added to typeinf_uncached to immediately widen any
This blows up way too quickly, so logic was added to `typeinf_uncached` to immediately widen any
argument that is a subtype of `Function` and that grows in depth down the stack.
Loading

0 comments on commit 56d976a

Please sign in to comment.