Index: vm/bitmap.cc |
=================================================================== |
--- vm/bitmap.cc (revision 0) |
+++ vm/bitmap.cc (revision 0) |
@@ -0,0 +1,120 @@ |
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#include "vm/bitmap.h" |
+ |
+#include "platform/assert.h" |
+#include "vm/object.h" |
+ |
+namespace dart { |
+ |
+bool BitmapBuilder::Get(int32_t bit_offset) const { |
+ if (!InRange(bit_offset)) { |
+ return false; |
+ } |
+ return GetBit(bit_offset); |
+} |
+ |
+ |
+void BitmapBuilder::Set(int32_t bit_offset, bool value) { |
+ while (!InRange(bit_offset)) { |
+ int32_t new_size = size_ + kIncrementSize; |
+ ASSERT(new_size > size_); |
+ uint8_t* new_bit_list = reinterpret_cast<uint8_t*>( |
+ Isolate::Current()->current_zone()->Allocate(new_size)); |
+ ASSERT(new_bit_list != NULL); |
+ uint8_t* old_bit_list = |
+ (size_ == kInitialSize) ? bit_list_ : bit_list_dynamic_; |
srdjan
2012/03/14 17:31:32
You could instead have bit_list_dynamic_ point to
siva
2012/03/14 22:54:20
Good point. Done.
On 2012/03/14 17:31:32, srdjan
|
+ memmove(new_bit_list, old_bit_list, size_); |
+ memset((new_bit_list + size_), 0, kIncrementSize); |
+ size_ = new_size; |
+ bit_list_dynamic_ = new_bit_list; |
+ } |
+ SetBit(bit_offset, value); |
+} |
+ |
+ |
+// Return the bit offset of the highest bit set. |
+int32_t BitmapBuilder::Maximum() const { |
+ int32_t bound = BitSize(); |
+ for (int32_t i = bound; i >= 0; i--) { |
srdjan
2012/03/14 17:31:32
intptr_t
siva
2012/03/14 22:54:20
Done.
|
+ if (Get(i)) return i; |
+ } |
+ return Bitmap::kNoMaximum; |
+} |
+ |
+ |
+// Return the bit offset of the lowest bit set. |
+int32_t BitmapBuilder::Minimum() const { |
+ int32_t bound = BitSize(); |
+ for (int32_t i = 0; i < bound; i++) { |
+ if (Get(i)) return i; |
+ } |
+ return Bitmap::kNoMinimum; |
+} |
+ |
+ |
+void BitmapBuilder::SetRange(int32_t min, int32_t max, bool value) { |
+ for (int32_t i = min; i <= max; i++) { |
+ Set(i, value); |
+ } |
+} |
+ |
+ |
+void BitmapBuilder::SetBits(const Bitmap& bitmap) { |
+ int32_t min = bitmap.Minimum(); |
+ int32_t max = bitmap.Maximum(); |
+ if (min == Bitmap::kNoMinimum || max == Bitmap::kNoMaximum) { |
+ return; |
+ } |
+ for (int32_t i = min; i <= max; i++) { |
+ Set(i, bitmap.Get(i)); |
+ } |
srdjan
2012/03/14 17:31:32
Don't you need to clear the bits outside Minimum..
siva
2012/03/14 22:54:20
Done.
|
+} |
+ |
+ |
+RawBitmap* BitmapBuilder::GetBitmap() const { |
+ const Bitmap& bmap = Bitmap::Handle(Bitmap::New(size_)); |
+ int32_t bound = BitSize(); |
+ for (int32_t i = 0; i < bound; i++) { |
+ bmap.SetBit(i, Get(i)); |
+ } |
+ return bmap.raw(); |
+} |
+ |
+ |
+bool BitmapBuilder::GetBit(int32_t bit_offset) const { |
+ ASSERT(InRange(bit_offset)); |
+ int byte_offset = bit_offset >> kBitsPerByteLog2; |
+ int bit_remainder = bit_offset & (kBitsPerByte - 1); |
+ uint8_t mask = 1U << bit_remainder; |
+ if (size_ == kInitialSize) { |
+ return ((bit_list_[byte_offset] & mask) != 0); |
+ } else { |
+ ASSERT(bit_list_dynamic_ != NULL); |
+ return ((bit_list_dynamic_[byte_offset] & mask) != 0); |
+ } |
+} |
+ |
+ |
+void BitmapBuilder::SetBit(int32_t bit_offset, bool value) { |
+ ASSERT(InRange(bit_offset)); |
+ int byte_offset = bit_offset >> kBitsPerByteLog2; |
+ int bit_remainder = bit_offset & (kBitsPerByte - 1); |
+ uint8_t mask = 1U << bit_remainder; |
+ uint8_t* byte_addr; |
+ if (size_ == kInitialSize) { |
+ byte_addr = &(bit_list_[byte_offset]); |
+ } else { |
+ ASSERT(bit_list_dynamic_ != NULL); |
+ byte_addr = &(bit_list_dynamic_[byte_offset]); |
+ } |
+ if (value) { |
+ *byte_addr |= mask; |
+ } else { |
+ *byte_addr &= ~mask; |
+ } |
+} |
+ |
+} // namespace dart |