[PATCH] add InternalVector to sanitizer_common

Sergey Matveev earthdok at google.com
Tue Feb 26 04:54:44 PST 2013


  as per kcc's suggestions

Hi kcc, samsonov, glider,

http://llvm-reviews.chandlerc.com/D463

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D463?vs=1104&id=1108#toc

Files:
  lib/sanitizer_common/sanitizer_common.h
  lib/sanitizer_common/tests/sanitizer_common_test.cc

Index: lib/sanitizer_common/sanitizer_common.h
===================================================================
--- lib/sanitizer_common/sanitizer_common.h
+++ lib/sanitizer_common/sanitizer_common.h
@@ -17,6 +17,7 @@
 #define SANITIZER_COMMON_H
 
 #include "sanitizer_internal_defs.h"
+#include "sanitizer_libc.h"
 
 namespace __sanitizer {
 struct StackTrace;
@@ -259,6 +260,57 @@
 # define FIRST_32_SECOND_64(a, b) (a)
 #endif
 
+// A low-level vector based on mmap. May incur a significant memory overhead for
+// small vectors.
+// WARNING: The current implementation supports only POD types.
+template<typename T>
+class InternalVector {
+ public:
+  explicit InternalVector(uptr initial_capacity) {
+    CHECK_GT(initial_capacity, 0);
+    capacity_ = initial_capacity;
+    size_ = 0;
+    data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalVector");
+  }
+  ~InternalVector() {
+    UnmapOrDie(data_, capacity_ * sizeof(T));
+  }
+  T &operator[](uptr i) {
+    CHECK_LT(i, size_);
+    return data_[i];
+  }
+  void push_back(const T &element) {
+    CHECK_LE(size_, capacity_);
+    if (size_ == capacity_) {
+      uptr new_capacity = RoundUpToPowerOfTwo(size_ + 1);
+      Resize(new_capacity);
+    }
+    data_[size_++] = element;
+  }
+  uptr size() {
+    return size_;
+  }
+
+ private:
+  void Resize(uptr new_capacity) {
+    CHECK_GT(new_capacity, 0);
+    CHECK_LE(size_, new_capacity);
+    T *new_data = (T *)MmapOrDie(new_capacity * sizeof(T),
+                                 "InternalVector");
+    internal_memcpy(new_data, data_, size_ * sizeof(T));
+    T *old_data = data_;
+    data_ = new_data;
+    UnmapOrDie(old_data, capacity_ * sizeof(T));
+    capacity_ = new_capacity;
+  }
+  // Disallow evil constructors.
+  InternalVector(const InternalVector&);
+  void operator=(const InternalVector&);
+
+  T *data_;
+  uptr capacity_;
+  uptr size_;
+};
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_COMMON_H
Index: lib/sanitizer_common/tests/sanitizer_common_test.cc
===================================================================
--- lib/sanitizer_common/tests/sanitizer_common_test.cc
+++ lib/sanitizer_common/tests/sanitizer_common_test.cc
@@ -96,4 +96,15 @@
 }
 #endif
 
+TEST(SanitizerCommon, InternalVector) {
+  InternalVector<uptr> vector(1);
+  for (uptr i = 0; i < 100; i++) {
+    EXPECT_EQ(vector.size(), i);
+    vector.push_back(i);
+  }
+  for (uptr i = 0; i < 100; i++) {
+    EXPECT_EQ(vector[i], i);
+  }
+}
+
 }  // namespace __sanitizer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D463.2.patch
Type: text/x-patch
Size: 2508 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130226/86a43df4/attachment.bin>


More information about the llvm-commits mailing list