Changeset a5db488 for libcfa/src
- Timestamp:
- May 5, 2021, 2:41:50 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 7f54356
- Parents:
- d653faf
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/containers/list2.hfa
rd653faf ra5db488 39 39 40 40 41 42 43 #define ORIGIN_TAG_BITNO 63 41 // The origin is the position encountered at the start of iteration, 42 // signifying, "need to advance to the first element," and at the end 43 // of iteration, signifying, "no more elements." Normal comsumption of 44 // an iterator runs ?`moveNext as the first step, and uses the return 45 // of ?`moveNext as a guard, before dereferencing the iterator. So 46 // normal consumption of an iterator does not dereference an iterator 47 // in origin position. The value of a pointer (underlying a refence) 48 // that is exposed publicly as an iteraor, and also a pointer stored 49 // internally in a link field, is tagged, to indicate "is the origin" 50 // (internally, is the list-head sentinel node), or untagged, to indicate 51 // "is a regular node." Intent is to help a user who dereferences an 52 // iterator in origin position (which would be an API-use error on their 53 // part), by failing fast. 54 55 #if defined( __x86_64 ) 56 // Preferred case: tag in the most-significant bit. Dereference 57 // has been shown to segfault consistently. Maintenance should 58 // list more architectures as "ok" here, to let them use the 59 // preferred case, when valid. 60 #define ORIGIN_TAG_BITNO ( 8 * sizeof( size_t ) - 1 ) 61 #else 62 // Fallback case: tag in the least-significant bit. Dereference 63 // will often give an alignment error, but may not, e.g. if 64 // accessing a char-typed member. 32-bit x86 uses the most- 65 // significant bit for real room on the heap. 66 #define ORIGIN_TAG_BITNO 0 67 #endif 44 68 #define ORIGIN_TAG_MASK (((size_t)1) << ORIGIN_TAG_BITNO) 45 69 … … 47 71 #define ORIGIN_TAG_CLEAR(p) ((p) & ~ORIGIN_TAG_MASK) 48 72 #define ORIGIN_TAG_QUERY(p) ((p) & ORIGIN_TAG_MASK) 49 50 // #define ORIGIN_TAG_SET(p) (p)51 // #define ORIGIN_TAG_CLEAR(p) (p)52 // #define ORIGIN_TAG_QUERY(p) (0)53 73 54 74 … … 110 130 tE & list_pos_raw = list_pos; 111 131 tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw ); 132 asm( "" : : : "memory" ); 112 133 tE & after_raw = * (list_pos_elem`inner`inner).next; 113 134 tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw ); … … 116 137 (after_elem`inner`inner).prev = &to_insert; 117 138 (list_pos_elem`inner`inner).next = &to_insert; 139 asm( "" : : : "memory" ); 118 140 } 119 141 … … 126 148 tE & list_pos_raw = list_pos; 127 149 tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw ); 150 asm( "" : : : "memory" ); 128 151 tE & before_raw = * (list_pos_elem`inner`inner).prev; 129 152 tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw ); … … 132 155 (before_elem`inner`inner).next = &to_insert; 133 156 (list_pos_elem`inner`inner).prev = &to_insert; 134 } 135 136 static inline void doRemove( 137 dlink(tE) & this_links, dlink(tE) & before_links, dlink(tE) & after_links, 138 tE & before_target, tE & after_target ) { 139 140 before_links.next = &after_target; 141 after_links.prev = &before_target; 142 143 asm( "" : : : "memory" ); 144 145 this_links.prev = 0p; 146 this_links.next = 0p; 147 } 148 149 static inline tE & remove(diref(tE, tLinks) list_pos) { 150 verify (&list_pos != 0p); 151 tE & list_pos_elem = list_pos; 152 verify( ! ORIGIN_TAG_QUERY((size_t) & list_pos_elem) ); 153 dlink(tE) & list_pos_links = list_pos_elem`inner`inner; 154 tE & before_raw = * list_pos_links.prev; 155 tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw ); 156 dlink(tE) & before_links = before_elem`inner`inner; 157 tE & after_raw = * list_pos_links.next; 158 tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw ); 159 dlink(tE) & after_links = after_elem`inner`inner; 160 161 doRemove(list_pos_links, before_links, after_links, before_raw, after_raw); 162 163 return list_pos_elem; 164 } 165 /* 157 asm( "" : : : "memory" ); 158 } 159 166 160 static inline tE & remove(diref(tE, tLinks) list_pos) { 167 161 verify (&list_pos != 0p); … … 177 171 before_links.next = &after_raw; 178 172 after_links.prev = &before_raw; 179 asm( "" : : : "memory" );173 asm( "" : : : "memory" ); 180 174 list_pos_links.prev = 0p; 181 175 list_pos_links.next = 0p; 176 asm( "" : : : "memory" ); 182 177 return list_pos_elem; 183 178 } 184 */ 179 185 180 static inline diref(tE, tLinks) ?`first( dlist(tE, tLinks) &lst ) { 186 181 tE * firstPtr = lst.next;
Note: See TracChangeset
for help on using the changeset viewer.