@@ -58,31 +58,29 @@ namespace {
58
58
// / A single access that we're tracking.
59
59
struct Access {
60
60
void *Pointer;
61
- uintptr_t HereAndAction;
62
- Access *Next;
61
+ uintptr_t NextAndAction;
63
62
64
63
enum : uintptr_t {
65
64
ActionMask = (uintptr_t )ExclusivityFlags::ActionMask,
66
- HereMask = ~ActionMask
65
+ NextMask = ~ActionMask
67
66
};
68
67
69
- Access ** getHere () const {
70
- return reinterpret_cast <Access**>(HereAndAction & HereMask );
68
+ Access *getNext () const {
69
+ return reinterpret_cast <Access*>(NextAndAction & NextMask );
71
70
}
72
71
73
- void setHere (Access **newHere) {
74
- HereAndAction = reinterpret_cast <uintptr_t >(newHere) | uintptr_t (getAccessAction ());
72
+ void setNext (Access *next) {
73
+ NextAndAction =
74
+ reinterpret_cast <uintptr_t >(next) | (NextAndAction & NextMask);
75
75
}
76
76
77
77
ExclusivityFlags getAccessAction () const {
78
- return ExclusivityFlags (HereAndAction & ActionMask);
78
+ return ExclusivityFlags (NextAndAction & ActionMask);
79
79
}
80
80
81
- void initialize (void *pointer, Access **here, ExclusivityFlags action) {
82
- assert (*here == nullptr && " not inserting to end of list" );
81
+ void initialize (void *pointer, Access *next, ExclusivityFlags action) {
83
82
Pointer = pointer;
84
- HereAndAction = reinterpret_cast <uintptr_t >(here) | uintptr_t (action);
85
- Next = nullptr ;
83
+ NextAndAction = reinterpret_cast <uintptr_t >(next) | uintptr_t (action);
86
84
}
87
85
};
88
86
@@ -99,8 +97,7 @@ class AccessSet {
99
97
void insert (Access *access, void *pointer, ExclusivityFlags flags) {
100
98
auto action = getAccessAction (flags);
101
99
102
- Access **curP = &Head;
103
- for (Access *cur = *curP; cur != nullptr ; curP = &cur->Next , cur = *curP) {
100
+ for (Access *cur = Head; cur != nullptr ; cur = cur->getNext ()) {
104
101
// Ignore accesses to different values.
105
102
if (cur->Pointer != pointer)
106
103
continue ;
@@ -118,15 +115,27 @@ class AccessSet {
118
115
pointer);
119
116
}
120
117
121
- access->initialize (pointer, curP, action);
122
- *curP = access;
118
+ // Insert to the front of the array so that remove tends to find it faster.
119
+ access->initialize (pointer, Head, action);
120
+ Head = access;
123
121
}
124
122
125
- static void remove (Access *access) {
126
- Access **here = access->getHere ();
127
- *here = access->Next ;
128
- if (access->Next != nullptr )
129
- access->Next ->setHere (here);
123
+ void remove (Access *access) {
124
+ auto cur = Head;
125
+ // Fast path: stack discipline.
126
+ if (cur == access) {
127
+ Head = cur->getNext ();
128
+ return ;
129
+ }
130
+
131
+ for (Access *last = cur; cur != nullptr ; last = cur, cur = cur->getNext ()) {
132
+ if (last == access) {
133
+ last->setNext (cur->getNext ());
134
+ return ;
135
+ }
136
+ }
137
+
138
+ swift_runtime_unreachable (" access not found in set" );
130
139
}
131
140
};
132
141
@@ -231,5 +240,5 @@ void swift::swift_endAccess(ValueBuffer *buffer) {
231
240
return ;
232
241
}
233
242
234
- AccessSet:: remove (access);
243
+ getAccessSet (pointer). remove (access);
235
244
}
0 commit comments