You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -38,19 +39,12 @@ Moreover, there is a per-call-frame `CallId` as well as some global tracking sta
38
39
// `nat` is the type of mathematical natural numbers, meaning we don't want to think about overflow.
39
40
// NOTE: Miri just uses `NonZeroU64` which, realistically, will not overflow because we only ever increment by 1.
40
41
typePtrId=nat;
42
+
/// For historic reasons we often call pointer IDs "tags".
43
+
typeTag=PtrId;
41
44
42
45
/// CallId: uniquely identifying a stack frame.
43
46
typeCallId=nat;
44
47
45
-
/// Extra per-pointer state (the "tag"), tracking how this pointer was computed
46
-
/// ("pointer provenance").
47
-
pubenumTag {
48
-
/// References are tagged: we know where they got created.
49
-
Tag(PtrId),
50
-
/// Raw pointers are not tracked.
51
-
Untagged,
52
-
}
53
-
54
48
/// Indicates which permission is granted (by this item to some pointers)
55
49
pubenumPermission {
56
50
/// Grants unique mutable access.
@@ -78,7 +72,7 @@ pub struct Stack {
78
72
/// Used *mostly* as a stack; never empty.
79
73
/// Invariants:
80
74
/// * Above a `SharedReadOnly` there can only be more `SharedReadOnly`.
81
-
/// * Except for `Untagged`, no tag occurs in the stack more than once.
75
+
/// * No tag occurs in the stack more than once.
82
76
borrows:Vec<Item>,
83
77
}
84
78
@@ -217,13 +211,13 @@ Using any item within a block is equivalent to using any other item in that same
217
211
218
212
When allocating memory, we have to initialize the `Stack` associated with the new locations, and we have to choose a `Tag` for the initial pointer to this memory.
219
213
220
-
- For heap allocations, the stack of each freshly allocated memory location is `Stack { borrows: vec![(Untagged: SharedReadWrite)] }`, and the initial pointer to that memory has tag `Untagged`.
221
-
- For global allocations (`static`, environment and program argument data, ...), we pick a fresh `id` associated with the global, and each time a pointer to the global is created, it gets tagged `Tag(id)`.
222
-
The stacks in that memory are initialized with `Stack { borrows: vec![(Tag(id): SharedReadWrite)] }`.
223
214
- Stack memory is handled by an environment (which is part of the information carried in a stack frame of the Rust abstract machine) that maps each local variable to a place.
224
215
A place is a pointer together with some other data that is not relevant here -- the key point is that a place, just like every other pointer, carries a tag.
225
-
When the local variable becomes live and its backing memory gets allocated, we generate a new pointer ID `id` by calling `Tracking::new_ptr` and use `Tag(id)` as tag for the place of this local variable.
226
-
We also initialize the stack of all the memory locations in this new memory allocation with `Stack { borrows: vec![(Tag(id): Unique)] }`.
216
+
When the local variable becomes live and its backing memory gets allocated, we generate a new pointer ID `id` by calling `Tracking::new_ptr` and use `id` as tag for the place of this local variable.
217
+
We also initialize the stack of all the memory locations in this new memory allocation with `Stack { borrows: vec![(id: Unique)] }`.
218
+
- For heap allocations, we pick a fresh `id` at allocation time. The stack of each freshly allocated memory location is `Stack { borrows: vec![(id: SharedReadWrite)] }`, and the initial pointer to that memory has tag `id`.
219
+
- For global allocations (`static`, environment and program argument data, ...), we pick a fresh `id` associated with the global, and each time a pointer to the global is created, it gets tagged `id`.
220
+
The stacks in that memory are initialized with `Stack { borrows: vec![(id: SharedReadWrite)] }`.
227
221
228
222
### Accessing memory
229
223
@@ -333,7 +327,7 @@ location.stack.grant(
333
327
When executing `Retag(kind, place)`, we check if `place` holds a reference (`&[mut] _`) or box (`Box<_>`), and if `kind == Raw` we also check each raw pointer (`*[const,mut] _`).
334
328
For those we perform the following steps:
335
329
336
-
1. We compute a fresh tag: `Untagged` for raw pointers, `Tag(Tracking::new_ptr_id())` for everything else.
330
+
1. We compute a fresh tag: `Tracking::new_ptr_id()`.
337
331
2. We determine if we will want to protect the items we are going to generate:
338
332
This is the case only if `kind == FnEntry` and the type of this pointer is a reference (not a box).
339
333
3. We perform reborrowing of the memory this pointer points to with the new tag and indicating whether we want protection, treating boxes as `RefKind::Unique { two_phase: false }`.
0 commit comments