Skip to content

Commit 4528e4f

Browse files
author
Tbkhi
authored
Update memory.md
Minor updates to formatting.
1 parent 7b0ef5b commit 4528e4f

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

src/memory.md

+30-29
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Memory Management in Rustc
22

3-
Rustc tries to be pretty careful how it manages memory. The compiler allocates
4-
_a lot_ of data structures throughout compilation, and if we are not careful,
5-
it will take a lot of time and space to do so.
3+
Generally `rustc` tries to be pretty careful how it manages memory. The
4+
compiler allocates _a lot_ of data structures throughout compilation, and if we
5+
are not careful, it will take a lot of time and space to do so.
66

77
One of the main way the compiler manages this is using [arena]s and [interning].
88

@@ -11,52 +11,53 @@ One of the main way the compiler manages this is using [arena]s and [interning].
1111

1212
## Arenas and Interning
1313

14-
We create a LOT of data structures during compilation. For performance reasons,
15-
we allocate them from a global memory pool; they are each allocated once from a
16-
long-lived *arena*. This is called _arena allocation_. This system reduces
17-
allocations/deallocations of memory. It also allows for easy comparison of
18-
types for equality: for each interned type `X`, we implemented [`PartialEq for
19-
X`][peqimpl], so we can just compare pointers. The [`CtxtInterners`] type
20-
contains a bunch of maps of interned types and the arena itself.
14+
Since A LOT of data structures are created during compilation, for performance
15+
reasons, we allocate them from a global memory pool. Each are allocated once
16+
from a long-lived *arena*. This is called _arena allocation_. This system
17+
reduces allocations/deallocations of memory. It also allows for easy comparison
18+
of types for equality: for each interned type `X`, we implemented [`PartialEq`
19+
for X][peqimpl], so we can just compare pointers. The [`CtxtInterners`] type
20+
contains a bunch of maps of interned types and the `arena` itself.
2121

2222
[peqimpl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#implementations
2323
[`CtxtInterners`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.CtxtInterners.html#structfield.arena
2424

2525
### Example: `ty::TyKind`
2626

27-
Taking the example of [`ty::TyKind`] which represents a type in the compiler (you
28-
can read more [here](./ty.md)). Each time we want to construct a type, the
29-
compiler doesn’t naively allocate from the buffer. Instead, we check if that
30-
type was already constructed. If it was, we just get the same pointer we had
31-
before, otherwise we make a fresh pointer. With this schema if we want to know
32-
if two types are the same, all we need to do is compare the pointers which is
33-
efficient. `TyKind` should never be constructed on the stack, and it would be unusable
34-
if done so.
35-
You always allocate them from this arena and you always intern them so they are
27+
Take [`ty::TyKind`] which represents a type in the compiler (you can read more
28+
[here](./ty.md)). Each time we want to construct a type, the compiler doesn’t
29+
naively allocate from the buffer. Instead, we check if that type was already
30+
constructed. If it was, we just get the same pointer we had before, otherwise
31+
we make a fresh pointer. With this schema if we want to know if two types are
32+
the same, all we need to do is compare pointers, which is efficient. `TyKind`
33+
should never be constructed on the stack, and it would be unusable if done so.
34+
You always allocate them from this `arena` and you always intern them so they
35+
are
3636
unique.
3737

38-
At the beginning of the compilation we make a buffer and each time we need to allocate a type we use
39-
some of this memory buffer. If we run out of space we get another one. The lifetime of that buffer
40-
is `'tcx`. Our types are tied to that lifetime, so when compilation finishes all the memory related
41-
to that buffer is freed and our `'tcx` references would be invalid.
38+
At the beginning of the compilation we make a buffer and each time we need to
39+
allocate a type we use some of this memory buffer. If we run out of space we
40+
get another one. The lifetime of that buffer is `'tcx`. Our types are tied to
41+
that lifetime, so when compilation finishes all the memory related to that
42+
buffer is freed and our `'tcx` references are invalidated.
4243

4344
In addition to types, there are a number of other arena-allocated data structures that you can
4445
allocate, and which are found in this module. Here are a few examples:
4546

4647
- [`GenericArgs`], allocated with `mk_args` – this will intern a slice of types, often used
47-
to specify the values to be substituted for generics args (e.g. `HashMap<i32, u32>` would be
48-
represented as a slice `&'tcx [tcx.types.i32, tcx.types.u32]`).
48+
to specify the values to be substituted for generics args (e.g. `HashMap<i32, u32>` would be
49+
represented as a slice `&'tcx [tcx.types.i32, tcx.types.u32]`).
4950
- [`TraitRef`], typically passed by value – a **trait reference** consists of a reference to a trait
5051
along with its various type parameters (including `Self`), like `i32: Display` (here, the def-id
5152
would reference the `Display` trait, and the args would contain `i32`). Note that `def-id` is
5253
defined and discussed in depth in the `AdtDef and DefId` section.
53-
- [`Predicate`] defines something the trait system has to prove (see `traits` module).
54+
- [`Predicate`] defines something the trait system has to prove (see [traits] module).
5455

5556
[`GenericArgs`]: ./generic_arguments.html#GenericArgs
56-
[`TraitRef`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TraitRef.html
5757
[`Predicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Predicate.html
58-
58+
[`TraitRef`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TraitRef.html
5959
[`ty::TyKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/sty/type.TyKind.html
60+
[traits]: ./traits/resolution.md
6061

6162
## The tcx and how it uses lifetimes
6263

@@ -78,7 +79,7 @@ the arenas, anyhow).
7879
### A Note On Lifetimes
7980

8081
The Rust compiler is a fairly large program containing lots of big data
81-
structures (e.g. the AST, HIR, and the type system) and as such, arenas and
82+
structures (e.g. the `AST`, `HIR`, and the type system) and as such, arenas and
8283
references are heavily relied upon to minimize unnecessary memory use. This
8384
manifests itself in the way people can plug into the compiler (i.e. the
8485
[driver](./rustc-driver.md)), preferring a "push"-style API (callbacks) instead

0 commit comments

Comments
 (0)