Home | History | Annotate | Download | only in rtl
      1 //===-- tsan_vector.h -------------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of ThreadSanitizer (TSan), a race detector.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 // Low-fat STL-like vector container.
     15 
     16 #ifndef TSAN_VECTOR_H
     17 #define TSAN_VECTOR_H
     18 
     19 #include "tsan_defs.h"
     20 #include "tsan_mman.h"
     21 
     22 namespace __tsan {
     23 
     24 template<typename T>
     25 class Vector {
     26  public:
     27   explicit Vector(MBlockType typ)
     28       : typ_(typ)
     29       , begin_()
     30       , end_()
     31       , last_() {
     32   }
     33 
     34   ~Vector() {
     35     if (begin_)
     36       internal_free(begin_);
     37   }
     38 
     39   void Reset() {
     40     if (begin_)
     41       internal_free(begin_);
     42     begin_ = 0;
     43     end_ = 0;
     44     last_ = 0;
     45   }
     46 
     47   uptr Size() const {
     48     return end_ - begin_;
     49   }
     50 
     51   T &operator[](uptr i) {
     52     DCHECK_LT(i, end_ - begin_);
     53     return begin_[i];
     54   }
     55 
     56   const T &operator[](uptr i) const {
     57     DCHECK_LT(i, end_ - begin_);
     58     return begin_[i];
     59   }
     60 
     61   T *PushBack(T v = T()) {
     62     EnsureSize(Size() + 1);
     63     end_[-1] = v;
     64     return &end_[-1];
     65   }
     66 
     67   void PopBack() {
     68     DCHECK_GT(end_, begin_);
     69     end_--;
     70   }
     71 
     72   void Resize(uptr size) {
     73     uptr old_size = Size();
     74     EnsureSize(size);
     75     if (old_size < size) {
     76       for (uptr i = old_size; i < size; i++)
     77         begin_[i] = T();
     78     }
     79   }
     80 
     81  private:
     82   const MBlockType typ_;
     83   T *begin_;
     84   T *end_;
     85   T *last_;
     86 
     87   void EnsureSize(uptr size) {
     88     if (size <= Size())
     89       return;
     90     if (size <= (uptr)(last_ - begin_)) {
     91       end_ = begin_ + size;
     92       return;
     93     }
     94     uptr cap0 = last_ - begin_;
     95     uptr cap = 2 * cap0;
     96     if (cap == 0)
     97       cap = 16;
     98     if (cap < size)
     99       cap = size;
    100     T *p = (T*)internal_alloc(typ_, cap * sizeof(T));
    101     if (cap0) {
    102       internal_memcpy(p, begin_, cap0 * sizeof(T));
    103       internal_free(begin_);
    104     }
    105     begin_ = p;
    106     end_ = begin_ + size;
    107     last_ = begin_ + cap;
    108   }
    109 
    110   Vector(const Vector&);
    111   void operator=(const Vector&);
    112 };
    113 }  // namespace __tsan
    114 
    115 #endif  // #ifndef TSAN_VECTOR_H
    116