@@ -4,65 +4,70 @@ Generally `rustc` tries to be pretty careful how it manages memory. The
4
4
compiler allocates _ a lot_ of data structures throughout compilation, and if we
5
5
are not careful, it will take a lot of time and space to do so.
6
6
7
- One of the main way the compiler manages this is using [ arena] s and [ interning] .
7
+ One of the main way the compiler manages this is using [ ` arena ` ] s and [ interning] .
8
8
9
- [ arena ] : https://en.wikipedia.org/wiki/Region-based_memory_management
9
+ [ ` arena` ] : https://en.wikipedia.org/wiki/Region-based_memory_management
10
10
[ interning ] : https://en.wikipedia.org/wiki/String_interning
11
11
12
12
## Arenas and Interning
13
13
14
14
Since A LOT of data structures are created during compilation, for performance
15
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
16
+ from a long-lived * ` arena ` * . This is called _ arena allocation_ . This system
17
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.
18
+ of types (more on types [ here] ( ./ty.md ) ) for equality: for each interned
19
+ type ` X ` , we implemented [ ` PartialEq ` for X] [ peqimpl ] , so we can just compare
20
+ pointers. The [ ` CtxtInterners ` ] type contains a bunch of maps of interned types
21
+ and the ` arena ` itself.
21
22
22
- [ peqimpl ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#implementations
23
23
[ `CtxtInterners` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.CtxtInterners.html#structfield.arena
24
+ [ peqimpl ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#implementations
24
25
25
26
### Example: ` ty::TyKind `
26
27
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
36
- unique.
28
+ Take [ ` ty::TyKind ` ] which represents a type in the compiler. Each time we want
29
+ to construct a type, the compiler doesn’t naively allocate from the buffer.
30
+ Instead, we check if that type was already constructed. If it was, we just get
31
+ the same pointer we had before, otherwise we make a fresh pointer. With this
32
+ schema if we want to know if two types are the same, all we need to do is
33
+ compare pointers, which is efficient. [ ` TyKind ` ] should never be constructed on
34
+ the stack, and it would be unusable if done so. You always allocate them from
35
+ this ` arena ` and you always intern them so they are unique.
37
36
38
37
At the beginning of the compilation we make a buffer and each time we need to
39
38
allocate a type we use some of this memory buffer. If we run out of space we
40
39
get another one. The lifetime of that buffer is ` 'tcx ` . Our types are tied to
41
40
that lifetime, so when compilation finishes all the memory related to that
42
41
buffer is freed and our ` 'tcx ` references are invalidated.
43
42
44
- In addition to types, there are a number of other arena-allocated data structures that you can
45
- allocate, and which are found in this module. Here are a few examples:
43
+ In addition to types, there are a number of other ` arena ` -allocated data
44
+ structures that you can allocate, and which are found in this module. Here are
45
+ a few examples:
46
46
47
- - [ ` GenericArgs ` ] , allocated with ` mk_args ` – this will intern a slice of types, often used
47
+ - [ ` GenericArgs ` ] , allocated with [ ` mk_args ` ] – this will intern a slice of types, often used
48
48
to specify the values to be substituted for generics args (e.g. ` HashMap<i32, u32> ` would be
49
49
represented as a slice ` &'tcx [tcx.types.i32, tcx.types.u32] ` ).
50
- - [ ` TraitRef ` ] , typically passed by value – a ** trait reference** consists of a reference to a trait
51
- along with its various type parameters (including ` Self ` ), like ` i32: Display ` (here, the def-id
52
- would reference the ` Display ` trait, and the args would contain ` i32 ` ). Note that ` def-id ` is
53
- defined and discussed in depth in the ` AdtDef and DefId ` section.
50
+ - [ ` TraitRef ` ] , typically passed by value – a ** trait reference** consists of a
51
+ reference to a trait along with its various type parameters (including
52
+ ` Self ` ), like ` i32: Display ` (here, the def-id would reference the ` Display `
53
+ trait, and the args would contain ` i32 ` ). Note that [ ` def-id ` ] is defined and
54
+ discussed in depth in the [ ` AdtDef ` and ` DefId ` ] section.
54
55
- [ ` Predicate ` ] defines something the trait system has to prove (see [ traits] module).
55
56
57
+ [ `AdtDef` and `DefId` ] : ./ty.md#adts-representation
58
+ [ `def-id` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html
56
59
[ `GenericArgs` ] : ./generic_arguments.html#GenericArgs
60
+ [ `mk_args` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.mk_args
57
61
[ `Predicate` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Predicate.html
58
62
[ `TraitRef` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TraitRef.html
59
63
[ `ty::TyKind` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/sty/type.TyKind.html
64
+ [ `TyKind` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/ty_kind/enum.TyKind.html
60
65
[ traits ] : ./traits/resolution.md
61
66
62
- ## The tcx and how it uses lifetimes
67
+ ## The ` tcx ` and how it uses lifetimes
63
68
64
- The ` tcx ` (" typing context" ) is the central data structure in the compiler. It is the context that
65
- you use to perform all manner of queries. The struct ` TyCtxt ` defines a reference to this shared
69
+ The typing context ( ` tcx ` ) is the central data structure in the compiler. It is the context that
70
+ you use to perform all manner of queries. The ` struct ` [ ` TyCtxt ` ] defines a reference to this shared
66
71
context:
67
72
68
73
``` rust,ignore
@@ -76,10 +81,13 @@ As you can see, the `TyCtxt` type takes a lifetime parameter. When you see a ref
76
81
lifetime like ` 'tcx ` , you know that it refers to arena-allocated data (or data that lives as long as
77
82
the arenas, anyhow).
78
83
84
+ [ `TyCtxt` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html
85
+
79
86
### A Note On Lifetimes
80
87
81
88
The Rust compiler is a fairly large program containing lots of big data
82
- structures (e.g. the ` AST ` , ` HIR ` , and the type system) and as such, arenas and
89
+ structures (e.g. the Abstract Syntax Tree (` AST ` ), [ High-Level Intermediate
90
+ Representation (` HIR ` )] [ hir ] , and the type system) and as such, arenas and
83
91
references are heavily relied upon to minimize unnecessary memory use. This
84
92
manifests itself in the way people can plug into the compiler (i.e. the
85
93
[ driver] ( ./rustc-driver.md ) ), preferring a "push"-style API (callbacks) instead
@@ -90,4 +98,5 @@ duplication while also preventing a lot of the ergonomic issues due to many
90
98
pervasive lifetimes. The [ ` rustc_middle::ty::tls ` ] [ tls ] module is used to access these
91
99
thread-locals, although you should rarely need to touch it.
92
100
101
+ [ hir ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/index.html
93
102
[ tls ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/tls/index.html
0 commit comments