Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Side by Side Diff: runtime/vm/bitmap.cc

Issue 10832410: Give a length field to stack bitmaps. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated review comments. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/bitmap.h ('k') | runtime/vm/bitmap_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/bitmap.h" 5 #include "vm/bitmap.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/object.h" 8 #include "vm/object.h"
9 9
10 namespace dart { 10 namespace dart {
11 11
12 void BitmapBuilder::SetLength(intptr_t new_length) {
13 // When this function is used to shorten the length, affected bits in the
14 // backing store need to be cleared because the implementation assumes it.
15 if (new_length < length_) {
16 // Byte offset containing the first bit to be cleared.
17 intptr_t byte_offset = new_length >> kBitsPerByteLog2;
18 if (byte_offset < data_size_in_bytes_) {
19 // First bit index (in the byte) to be cleared.
20 intptr_t bit_index = new_length & (kBitsPerByte - 1);
21 intptr_t mask = (1 << bit_index) - 1;
22 data_[byte_offset] &= mask;
23 // Clear the rest.
24 ++byte_offset;
25 if (byte_offset < data_size_in_bytes_) {
26 memset(&data_[byte_offset], 0, data_size_in_bytes_ - byte_offset);
27 }
28 }
29 }
30 length_ = new_length;
31 }
32
33
12 bool BitmapBuilder::Get(intptr_t bit_offset) const { 34 bool BitmapBuilder::Get(intptr_t bit_offset) const {
13 if (!InRange(bit_offset)) { 35 ASSERT(InRange(bit_offset));
14 return false; 36 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
15 } 37 // Bits not covered by the backing store are implicitly false.
16 return GetBit(bit_offset); 38 return (byte_offset < data_size_in_bytes_) && GetBit(bit_offset);
17 } 39 }
18 40
19 41
20 void BitmapBuilder::Set(intptr_t bit_offset, bool value) { 42 void BitmapBuilder::Set(intptr_t bit_offset, bool value) {
21 while (!InRange(bit_offset)) { 43 ASSERT(bit_offset >= 0);
22 intptr_t new_size = size_in_bytes_ + kIncrementSizeInBytes; 44 if (!InRange(bit_offset)) {
23 ASSERT(new_size > 0); 45 length_ = bit_offset + 1;
24 uint8_t* new_bit_list = 46 // Bits not covered by the backing store are implicitly false.
25 Isolate::Current()->current_zone()->Alloc<uint8_t>(new_size); 47 if (!value) return;
26 ASSERT(new_bit_list != NULL); 48 // Grow the backing store if necessary.
27 ASSERT(bit_list_ != NULL); 49 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
28 uint8_t* old_bit_list = bit_list_; 50 if (byte_offset >= data_size_in_bytes_) {
29 memmove(new_bit_list, old_bit_list, size_in_bytes_); 51 uint8_t* old_data = data_;
30 memset((new_bit_list + size_in_bytes_), 0, kIncrementSizeInBytes); 52 intptr_t old_size = data_size_in_bytes_;
31 size_in_bytes_ = new_size; 53 data_size_in_bytes_ =
32 bit_list_ = new_bit_list; 54 Utils::RoundUp(byte_offset + 1, kIncrementSizeInBytes);
55 ASSERT(data_size_in_bytes_ > 0);
56 data_ = Isolate::Current()->current_zone()->Alloc<uint8_t>(
57 data_size_in_bytes_);
58 ASSERT(data_ != NULL);
59 memmove(data_, old_data, old_size);
60 memset(&data_[old_size], 0, (data_size_in_bytes_ - old_size));
61 }
33 } 62 }
34 SetBit(bit_offset, value); 63 SetBit(bit_offset, value);
35 } 64 }
36 65
37 66
38 // Return the bit offset of the highest bit set.
39 intptr_t BitmapBuilder::Maximum() const {
40 intptr_t bound = SizeInBits();
41 for (intptr_t i = (bound - 1); i >= 0; i--) {
42 if (Get(i)) return i;
43 }
44 return Stackmap::kNoMaximum;
45 }
46
47
48 // Return the bit offset of the lowest bit set.
49 intptr_t BitmapBuilder::Minimum() const {
50 intptr_t bound = SizeInBits();
51 for (intptr_t i = 0; i < bound; i++) {
52 if (Get(i)) return i;
53 }
54 return Stackmap::kNoMinimum;
55 }
56
57
58 void BitmapBuilder::SetRange(intptr_t min, intptr_t max, bool value) { 67 void BitmapBuilder::SetRange(intptr_t min, intptr_t max, bool value) {
59 for (intptr_t i = min; i <= max; i++) { 68 for (intptr_t i = min; i <= max; i++) {
60 Set(i, value); 69 Set(i, value);
61 } 70 }
62 } 71 }
63 72
64 73
65 bool BitmapBuilder::GetBit(intptr_t bit_offset) const { 74 bool BitmapBuilder::GetBit(intptr_t bit_offset) const {
66 ASSERT(InRange(bit_offset)); 75 ASSERT(InRange(bit_offset));
67 int byte_offset = bit_offset >> kBitsPerByteLog2; 76 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
68 int bit_remainder = bit_offset & (kBitsPerByte - 1); 77 ASSERT(byte_offset < data_size_in_bytes_);
78 intptr_t bit_remainder = bit_offset & (kBitsPerByte - 1);
69 uint8_t mask = 1U << bit_remainder; 79 uint8_t mask = 1U << bit_remainder;
70 ASSERT(bit_list_ != NULL); 80 ASSERT(data_ != NULL);
71 return ((bit_list_[byte_offset] & mask) != 0); 81 return ((data_[byte_offset] & mask) != 0);
72 } 82 }
73 83
74 84
75 void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) { 85 void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) {
76 ASSERT(InRange(bit_offset)); 86 ASSERT(InRange(bit_offset));
77 int byte_offset = bit_offset >> kBitsPerByteLog2; 87 int byte_offset = bit_offset >> kBitsPerByteLog2;
88 ASSERT(byte_offset < data_size_in_bytes_);
78 int bit_remainder = bit_offset & (kBitsPerByte - 1); 89 int bit_remainder = bit_offset & (kBitsPerByte - 1);
79 uint8_t mask = 1U << bit_remainder; 90 uint8_t mask = 1U << bit_remainder;
80 uint8_t* byte_addr; 91 ASSERT(data_ != NULL);
81 ASSERT(bit_list_ != NULL);
82 byte_addr = &(bit_list_[byte_offset]);
83 if (value) { 92 if (value) {
84 *byte_addr |= mask; 93 data_[byte_offset] |= mask;
85 } else { 94 } else {
86 *byte_addr &= ~mask; 95 data_[byte_offset] &= ~mask;
87 } 96 }
88 } 97 }
89 98
90 } // namespace dart 99 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/bitmap.h ('k') | runtime/vm/bitmap_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698