Changeset a5db488


Ignore:
Timestamp:
May 5, 2021, 2:41:50 PM (3 years ago)
Author:
Michael Brooks <mlbrooks@…>
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
Message:

Fixing two bugs in new linked list, which last night's build failure revealed.

  1. Adding more gcc-optimization reorder barriers and removing an unnecesary factoring around an incumbent one.
  1. Adjusting pointer-tagging to work on 32-bit.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/containers/list2.hfa

    rd653faf ra5db488  
    3939
    4040
    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
    4468#define ORIGIN_TAG_MASK (((size_t)1) << ORIGIN_TAG_BITNO)
    4569
     
    4771#define ORIGIN_TAG_CLEAR(p) ((p) & ~ORIGIN_TAG_MASK)
    4872#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)
    5373
    5474
     
    110130        tE & list_pos_raw = list_pos;
    111131        tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw );
     132        asm( "" : : : "memory" );
    112133        tE & after_raw = * (list_pos_elem`inner`inner).next;
    113134        tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw );
     
    116137        (after_elem`inner`inner).prev = &to_insert;
    117138                (list_pos_elem`inner`inner).next = &to_insert;
     139        asm( "" : : : "memory" );
    118140        }
    119141
     
    126148        tE & list_pos_raw = list_pos;
    127149        tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw );
     150        asm( "" : : : "memory" );
    128151        tE & before_raw = * (list_pos_elem`inner`inner).prev;
    129152        tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw );
     
    132155        (before_elem`inner`inner).next = &to_insert;
    133156                (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
    166160        static inline tE & remove(diref(tE, tLinks) list_pos) {
    167161                verify (&list_pos != 0p);
     
    177171        before_links.next = &after_raw;
    178172        after_links.prev = &before_raw;
    179 asm( "" : : : "memory" );
     173        asm( "" : : : "memory" );
    180174                list_pos_links.prev = 0p;
    181175                list_pos_links.next = 0p;
     176        asm( "" : : : "memory" );
    182177        return list_pos_elem;
    183178        }
    184 */
     179
    185180    static inline diref(tE, tLinks) ?`first( dlist(tE, tLinks) &lst ) {
    186181        tE * firstPtr = lst.next;
Note: See TracChangeset for help on using the changeset viewer.