Skip to content

Commit

Permalink
Remove some double spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandrejbr committed Apr 8, 2017
1 parent 4d358a4 commit dfd4e5a
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 67 deletions.
6 changes: 3 additions & 3 deletions ap-beam_instructions.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Here the meta information +{function, id, 1, 4}+ tells us that
execution of the id/1 function will start at label 4. At label 4 we do
an +is_integer+ on x0 and if we fail we jump to label 3 (f3) which
points to the func_info instruction, which will generate a _function
clause_ exception. Otherwise we just fall through and return the
clause_ exception. Otherwise we just fall through and return the
argument (x0).

=== Test instructions
Expand Down Expand Up @@ -91,7 +91,7 @@ compare any two terms. You can for example test if the atom +self+
is less than the pid returned by +self()+. (It is.)

Note that for numbers the comparison is done on the Erlang type
_number_, see xref:CH-TypeSystem[]. That is, for a mixed float and
_number_, see xref:CH-TypeSystem[]. That is, for a mixed float and
integer comparison the number of lower precision is converted to the
other type before comparison. For example on my system 1 and 0.1
compares as equal, as well as 9999999999999999 and 1.0e16.
Expand Down Expand Up @@ -160,7 +160,7 @@ context switch.
==== +bif0 Bif Reg+, +bif1 Lbl Bif Arg Reg+, +bif2 Lbl Bif Arg1 Arg2 Reg+
Call the bif +Bif+ with the given arguments, and store the result in
+Reg+. If the bif fails jump to +Lbl+. No zero arity bif can fail an
+Reg+. If the bif fails jump to +Lbl+. No zero arity bif can fail an
thus those calls doesn't take a fail label.
// Bif called by these instructions may not allocate on the heap nor
Expand Down
16 changes: 8 additions & 8 deletions beam.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
== The Erlang Virtual Machine: BEAM

BEAM (Bogumil's/Björn's Abstract Machine) is the machine that executes
the code in the Erlang Runtime System. It is a garbage collecting,
the code in the Erlang Runtime System. It is a garbage collecting,
reduction counting, virtual, non-preemptive, directly threaded,
register machine. If that doesn't tell you much, don't worry, in the
register machine. If that doesn't tell you much, don't worry, in the
following sections we will go through what each of those words means
in this context.

Expand Down Expand Up @@ -335,7 +335,7 @@ _subroutine threaded code_.
// TODO make sure to use the right terminology for different threaded code types.

This approach will make the decoding simpler at runtime, but it makes
the whole VM more complicated by requiring a loader. The loader
the whole VM more complicated by requiring a loader. The loader
replaces the byte code instructions with addresses to
functions implementing the instructions.

Expand Down Expand Up @@ -414,15 +414,15 @@ void stop() { running = 0; }
-------------------------------------------

In BEAM this concept is taken one step further, and BEAM uses
_directly threaded code_ (sometimes called only _thread code_). In
_directly threaded code_ (sometimes called only _thread code_). In
directly threaded code the call and return sequence is replaced by
direct jumps to the implementation of the next instruction. In order
direct jumps to the implementation of the next instruction. In order
to implement this in C, BEAM uses the GCC extension "labels as
values".

We will look closer at the BEAM emulator later but we will take a
quick look at how the add instruction is implemented. The code is
somewhat hard to follow due to the heavy usage of macros. The
somewhat hard to follow due to the heavy usage of macros. The
STORE_ARITH_RESULT macro actually hides the dispatch function which
looks something like: _I += 4; Goto(*I);_.

Expand Down Expand Up @@ -541,7 +541,7 @@ as "+goto*+".
Now imagine that the compile C code for these instructions end up at
memory addresses 0x3000, 0x3100, and 0x3200. When the BEAM code is
loaded the three move instructions in the code will be replaced by the
memory addresses of the implementation of the instructions. Imagine
memory addresses of the implementation of the instructions. Imagine
that the code (+{move,{x,0},{x,1}}, {move,{y,0},{x,0}},
{move,{x,1},{y,0}}+) is loaded at address 0x1000:

Expand Down Expand Up @@ -592,7 +592,7 @@ tuple. This would make it very hard to traverse a suspended process
stack and heap.

On the language level all processes are running concurrently and the
programmer should not have to deal with explicit yields. BEAM solves
programmer should not have to deal with explicit yields. BEAM solves
this by keeping track of how long a process has been running. This is
done by counting _reductions_. The term originaly comes from the
mathematical term beta-reduction used in lambda calculus.
Expand Down
8 changes: 4 additions & 4 deletions beam_instructions.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ between Erlang versions, especially between major versions.
This is the instruction set which we will cover in this chapter.

The other instruction set, the specific, is an optimized instruction
set used by the Beam to implement the external instruction set. To
set used by the Beam to implement the external instruction set. To
give you an understanding of how the Beam works we will cover this
instruction set in xref:CH-Internal_instructions[]. The internal
instruction set can change without warning between minor version or
Expand Down Expand Up @@ -143,7 +143,7 @@ beamexmaple.S file:
In addition to the actual beam code for the integer identity
function we also get some meta instructions.

The first line +{module, beamexample1}. %% version = 0+ tells
The first line +{module, beamexample1}. %% version = 0+ tells
us the module name "beamexample1" and the version number for
the instruction set "0".

Expand Down Expand Up @@ -187,7 +187,7 @@ is thrown.

The other two functions in the file are auto generated. If we look at
the second function the instruction +{move,{x,0},{x,1}}+ moves the
argument in register x0 to the second argument register x1. Then the
argument in register x0 to the second argument register x1. Then the
instruction +{move,{atom,beamexample1},{x,0}}+ moves the module name
atom to the first argument register x1. Finally a tail call is made to
+erlang:get_module_info/2+
Expand Down Expand Up @@ -342,7 +342,7 @@ pointer in X0. (It also removes any timeout, more on this soon.)

==== A Selective Receive Loop

For a selective receive like e.g. +receive [] -> ok end+ we will
For a selective receive like e.g. +receive [] -> ok end+ we will
loop over the message queue to check if any message in the queue
matches.

Expand Down
6 changes: 3 additions & 3 deletions compiler.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ has become as popular and widely used as e.g. QLC.
OK, so you know you shouldn't use it, but if you have to, here is what
you need to know. A parse transforms is a function that works on the
abstract syntax tree (AST) (see
link:http://www.erlang.org/doc/apps/erts/absform.html[] ). The compiler
link:http://www.erlang.org/doc/apps/erts/absform.html[] ). The compiler
does preprocessing, tokenization and parsing and then it will call the
parse transform function with the AST and expects to get back a
new AST.
Expand Down Expand Up @@ -422,7 +422,7 @@ which occures after the parse transform pass.

The documenation of the abstract format is somewhat dense and it is
quite hard to get a grip on the abstract format by reading the
documentation. I encourage you to use the _syntax_tools_ and
documentation. I encourage you to use the _syntax_tools_ and
especially +erl_syntax_lib+ for any serious work on the AST.

Here we will develop a a simple parse transform just to get an
Expand Down Expand Up @@ -684,7 +684,7 @@ Pattern matching is compiled to more primitive operations.

==== Compiler Pass: BEAM Code
The last step of a normal compilation is the external beam code
format. Some low level optimizations such as dead code elimination and
format. Some low level optimizations such as dead code elimination and
peep hole optimisations are done on this level.

The BEAM code is described in detail in
Expand Down
10 changes: 5 additions & 5 deletions introduction.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ how the runtime system works.

In the following chapters of xref:P-ERTS[] I will try to explain each
component of the system by itself, in one separate chapter for each of
the major component. You should be able to read any one of these
the major component. You should be able to read any one of these
chapters without having a full understanding of how the other
components are implemented, but you will need a basic understanding of
what each component is. The rest of this introductory chapter should
Expand Down Expand Up @@ -100,12 +100,12 @@ two Erlang nodes running on one machine.

In the bottom of the stack there is the hardware you are running
on. The easiest way to improve the performance of your app is probably
to run it on better hardware. If economical or physical constraints
to run it on better hardware. If economical or physical constraints
wont let you upgrade your hardware you can start exploring higher
levels of the stack. The two most important choices for your hardware
is whether it is multicore and whether it is 32-bit or 64-bit. You
need different builds of ERTS depending on whether you want to use
multicore or not and whether you want to use 32-bit or 64-bit. (See
multicore or not and whether you want to use 32-bit or 64-bit. (See
xref:CH-BuildingERTS[] for information on how to build different
versions of ERTS.) This book will not go into any details about
hardware but I will talk a bit about multicore and NUMA architectures
Expand Down Expand Up @@ -139,7 +139,7 @@ The fifth layer, OTP(((OTP))), supplies the Erlang standard
libraries. OTP originally stood for "Open Telecom Platform" and was a
number of Erlang libraries supplying building blocks (such as
+supervisor+, +gen_server+ and +gen_ftp+) for building robust
applications (such as telephony exchanges). Early on, the libraries
applications (such as telephony exchanges). Early on, the libraries
and the meaning of OTP got intermingled with all the other standard
libraries shipped with ERTS. Nowadays most people use OTP together
with Erlang in "Erlang/OTP" as the name for ERTS and all Erlang
Expand Down Expand Up @@ -255,7 +255,7 @@ running at the same time as all other processes, but in reality there
is just one process running in the VM. On a multicore machine Erlang
actually runs more than one scheduler, usually one per physical core,
each having their own queues. This way Erlang achieves true
parallelism. To utilize more than one core ERTS has to be built (see
parallelism. To utilize more than one core ERTS has to be built (see
xref:CH-BuildingERTS[]) in _SMP_(((SMP))) mode. SMP stands for
_Symetric MultiProcessing_, that is, the ability to execute a
processes on any one of multiple CPUs.
Expand Down
4 changes: 2 additions & 2 deletions io.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ There are three different classes of ports: file descriptors, external
programs and drivers. A file descriptor port makes it possible for a
process to access an already opened file descriptor. A port to an
external program invokes the external program as a separate OS
process. A driver port requires a driver to be loaded in the Erlang
process. A driver port requires a driver to be loaded in the Erlang
node.

All ports are created by a call to +erlang:open_port(PortName,
Expand Down Expand Up @@ -110,7 +110,7 @@ predefined port types. There are the common drivers available on all
platforms: tcp_inet, udp_inet, sctp_inet, efile, zlib_drv,
ram_file_drv, binary_filer, tty_sl. These drivers are used to
implement e.g. file handling and sockets in Erlang. On Windows there
is also a driver to access the registry: registry__drv__. And on most
is also a driver to access the registry: registry__drv__. And on most
platforms there are example drivers to use when implementing your own
driver like: multi and sig_drv.

Expand Down
18 changes: 9 additions & 9 deletions memory.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ If the underlying operating system supports mmap a specific memory
allocator can use mseg_alloc instead of sys_alloc to allocate
memory from the operating system.

Memory areas allocated through mseg_alloc are called segments. When a
Memory areas allocated through mseg_alloc are called segments. When a
segment is freed it is not immediately returned to the OS, instead it
is kept in a segment cache.

Expand Down Expand Up @@ -283,7 +283,7 @@ In a smp system there is usually one allocator of each type per
scheduler thread.

The smallest unit of memory that an allocator work with is called a
_block_. When you call an allocator to allocate a certain amount of
_block_. When you call an allocator to allocate a certain amount of
memory what you get back is a block. It is also blocks that you give
as an argument to the allocator when you want to deallocate memory.

Expand Down Expand Up @@ -406,7 +406,7 @@ __________________________
==== The temporary allocator: temp_alloc

The allocator _temp_alloc_, is used for temporary
allocations. That is very short lived allocations. Memory allocated
allocations. That is very short lived allocations. Memory allocated
by temp_alloc may not be allocated over a Erlang process context
switch.

Expand Down Expand Up @@ -450,7 +450,7 @@ where tagged Erlang terms are stored, such as Erlang process heaps
(all generations), heap fragments, and the beam_registers.

This is probably the memory areas you are most interested in as an
Erlang developer or when tuning an Erlang system. We will talk more
Erlang developer or when tuning an Erlang system. We will talk more
about how these areas are managed in the upcoming sections on garbage
collection and process memory. There we will also cover what a heap
fragment is.
Expand Down Expand Up @@ -556,7 +556,7 @@ objects.
==== Term sharing

Objects on the heap are passed by references within the context of one
process. If you call one function with a tuple as an argument, then
process. If you call one function with a tuple as an argument, then
only a tagged reference to that tuple is passed to the called
function. When you build new terms you will also only use references
to sub terms.
Expand Down Expand Up @@ -909,7 +909,7 @@ This part of the content seems to be good, and probably worthy of being a top-le


When a process runs out of space on the stack and heap the process
will try to reclaim space by doing a minor garbage collection. The
will try to reclaim space by doing a minor garbage collection. The
code for this can be found in
link:https://github.com/erlang/otp/blob/maint/erts/emulator/beam/erl_gc.c[erl_gc.c].

Expand Down Expand Up @@ -1055,15 +1055,15 @@ way. (see xref:AP-listings[] for the definitions of the scripts in gdb_script.)

Here we can see the heap of the process after it has allocated the
list "Hello" on the heap and the cons containing that list twice, and
the tuple containing the cons and the list. The _root set_, in this
the tuple containing the cons and the list. The _root set_, in this
case the stack, contains a pointer to the cons containing two copies
of the list. The tuple is dead, that is, there are no references to
of the list. The tuple is dead, that is, there are no references to
it.

The garbage collection starts by calculating the root set and by
allocating a new heap (_to space_). By stepping into the gc code in the
debugger you can see how this is done. I will not go through the
details here. After a number of steps the execution will reach the
details here. After a number of steps the execution will reach the
point where all terms in the root set are copied to the new heap. This
starts around (depending on version) line 1272 with a +while+ loop in
erl_gc.c.
Expand Down
4 changes: 2 additions & 2 deletions preface.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ About this book


For anyone who: Want to tune an Erlang installation. Want to know how
to debug VM crashes. Want to improve performance of Erlang
to debug VM crashes. Want to improve performance of Erlang
applications. Want to understand how Erlang really works. Want to
learn how to build your own runtime environment.

Expand Down Expand Up @@ -68,7 +68,7 @@ _parallelism_. In this book _concurrency_ is the concept of having
two or more processes that *can* execute independently of each other,
this can be done by first executing one process then the other or by
interleaving the execution, or by executing the processes in
parallel. With _parallel_ executions we mean that the processes
parallel. With _parallel_ executions we mean that the processes
actually execute at the exact same time by using several physical
execution units. Parallelism can be achieved on different levels.
Through multiple execution units in the execution pipeline in one core,
Expand Down
Loading

0 comments on commit dfd4e5a

Please sign in to comment.