ART: Remove TODO in BitVector

Refactor the BitVector constructor: split it up to remove the
possibility to provide contradicting parameters, and add a custom
copying constructor.

Change-Id: Ie943f279baa007db578aea0f2f33fa93311612ee
diff --git a/compiler/dex/gvn_dead_code_elimination.cc b/compiler/dex/gvn_dead_code_elimination.cc
index 044989e..d29b865 100644
--- a/compiler/dex/gvn_dead_code_elimination.cc
+++ b/compiler/dex/gvn_dead_code_elimination.cc
@@ -74,7 +74,7 @@
 GvnDeadCodeElimination::VRegChains::VRegChains(uint32_t num_vregs, ScopedArenaAllocator* alloc)
     : num_vregs_(num_vregs),
       vreg_data_(alloc->AllocArray<VRegValue>(num_vregs, kArenaAllocMisc)),
-      vreg_high_words_(num_vregs, false, Allocator::GetNoopAllocator(),
+      vreg_high_words_(false, Allocator::GetNoopAllocator(),
                        BitVector::BitsToWords(num_vregs),
                        alloc->AllocArray<uint32_t>(BitVector::BitsToWords(num_vregs))),
       mir_data_(alloc->Adapter()) {
diff --git a/runtime/base/bit_vector.cc b/runtime/base/bit_vector.cc
index 39ce0d2..cfd3d24 100644
--- a/runtime/base/bit_vector.cc
+++ b/runtime/base/bit_vector.cc
@@ -24,11 +24,7 @@
 
 namespace art {
 
-// TODO: replace excessive argument defaulting when we are at gcc 4.7
-// or later on host with delegating constructor support. Specifically,
-// starts_bits and storage_size/storage are mutually exclusive.
-BitVector::BitVector(uint32_t start_bits,
-                     bool expandable,
+BitVector::BitVector(bool expandable,
                      Allocator* allocator,
                      uint32_t storage_size,
                      uint32_t* storage)
@@ -36,12 +32,31 @@
     storage_size_(storage_size),
     allocator_(allocator),
     expandable_(expandable) {
+  DCHECK(storage_ != nullptr);
+
   static_assert(sizeof(*storage_) == kWordBytes, "word bytes");
   static_assert(sizeof(*storage_) * 8u == kWordBits, "word bits");
-  if (storage_ == nullptr) {
-    storage_size_ = BitsToWords(start_bits);
-    storage_ = static_cast<uint32_t*>(allocator_->Alloc(storage_size_ * kWordBytes));
-  }
+}
+
+BitVector::BitVector(uint32_t start_bits,
+                     bool expandable,
+                     Allocator* allocator)
+  : BitVector(expandable,
+              allocator,
+              BitsToWords(start_bits),
+              static_cast<uint32_t*>(allocator->Alloc(BitsToWords(start_bits) * kWordBytes))) {
+}
+
+
+BitVector::BitVector(const BitVector& src,
+                     bool expandable,
+                     Allocator* allocator)
+  : BitVector(expandable,
+              allocator,
+              src.storage_size_,
+              static_cast<uint32_t*>(allocator->Alloc(src.storage_size_ * kWordBytes))) {
+  // Direct memcpy would be faster, but this should be fine too and is cleaner.
+  Copy(&src);
 }
 
 BitVector::~BitVector() {
@@ -357,4 +372,8 @@
   }
 }
 
+Allocator* BitVector::GetAllocator() const {
+  return allocator_;
+}
+
 }  // namespace art
diff --git a/runtime/base/bit_vector.h b/runtime/base/bit_vector.h
index afa8dc1..9b55e70 100644
--- a/runtime/base/bit_vector.h
+++ b/runtime/base/bit_vector.h
@@ -113,9 +113,16 @@
 
   BitVector(uint32_t start_bits,
             bool expandable,
+            Allocator* allocator);
+
+  BitVector(bool expandable,
             Allocator* allocator,
-            uint32_t storage_size = 0,
-            uint32_t* storage = nullptr);
+            uint32_t storage_size,
+            uint32_t* storage);
+
+  BitVector(const BitVector& src,
+            bool expandable,
+            Allocator* allocator);
 
   virtual ~BitVector();
 
@@ -245,6 +252,8 @@
 
   void Dump(std::ostream& os, const char* prefix) const;
 
+  Allocator* GetAllocator() const;
+
  private:
   /**
    * @brief Dump the bitvector into buffer in a 00101..01 format.
diff --git a/runtime/base/bit_vector_test.cc b/runtime/base/bit_vector_test.cc
index 19c01f2..0e3df76 100644
--- a/runtime/base/bit_vector_test.cc
+++ b/runtime/base/bit_vector_test.cc
@@ -71,7 +71,7 @@
   uint32_t bits[kWords];
   memset(bits, 0, sizeof(bits));
 
-  BitVector bv(0U, false, Allocator::GetNoopAllocator(), kWords, bits);
+  BitVector bv(false, Allocator::GetNoopAllocator(), kWords, bits);
   EXPECT_EQ(kWords, bv.GetStorageSize());
   EXPECT_EQ(kWords * sizeof(uint32_t), bv.GetSizeOf());
   EXPECT_EQ(bits, bv.GetRawStorage());
@@ -128,7 +128,7 @@
   uint32_t bits[kWords];
   memset(bits, 0, sizeof(bits));
 
-  BitVector bv(0U, false, Allocator::GetNoopAllocator(), kWords, bits);
+  BitVector bv(false, Allocator::GetNoopAllocator(), kWords, bits);
   bv.SetInitialBits(0u);
   EXPECT_EQ(0u, bv.NumSetBits());
   bv.SetInitialBits(1u);