Flutter Engine
The Flutter Engine
bitmap.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/bitmap.h"
6
7#include "platform/assert.h"
8#include "vm/log.h"
9#include "vm/object.h"
10
11namespace dart {
12
13void BitmapBuilder::SetLength(intptr_t new_length) {
14 // When this function is used to shorten the length, affected bits in the
15 // backing store need to be cleared because the implementation assumes it.
16 if (new_length < length_) {
17 // Byte offset containing the first bit to be cleared.
18 intptr_t byte_offset = new_length >> kBitsPerByteLog2;
19 if (byte_offset < data_size_in_bytes_) {
20 // First bit index (in the byte) to be cleared.
21 intptr_t bit_index = new_length & (kBitsPerByte - 1);
22 intptr_t mask = (1 << bit_index) - 1;
23 BackingStore()[byte_offset] &= mask;
24 // Clear the rest.
25 ++byte_offset;
26 if (byte_offset < data_size_in_bytes_) {
27 memset(&BackingStore()[byte_offset], 0,
28 data_size_in_bytes_ - byte_offset);
29 }
30 }
31 }
32 length_ = new_length;
33}
34
35bool BitmapBuilder::Get(intptr_t bit_offset) const {
36 if (!InRange(bit_offset)) {
37 return false;
38 }
39 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
40 // Bits not covered by the backing store are implicitly false.
41 return (byte_offset < data_size_in_bytes_) && GetBit(bit_offset);
42}
43
44void BitmapBuilder::Set(intptr_t bit_offset, bool value) {
45 if (!InRange(bit_offset)) {
46 length_ = bit_offset + 1;
47 }
48
49 // Bits not covered by the backing store are implicitly false.
50 // Grow the backing store if necessary.
51 if (value) {
52 if (!InBackingStore(bit_offset)) {
53 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
54 uint8_t* old_data = BackingStore();
55 intptr_t old_size = data_size_in_bytes_;
56 data_size_in_bytes_ =
57 Utils::RoundUp(byte_offset + 1, kIncrementSizeInBytes);
58 ASSERT(data_size_in_bytes_ > 0);
59 // Note: do not update data_ yet because it might overwrite old_data
60 // contents.
61 uint8_t* new_data = AllocBackingStore(data_size_in_bytes_);
62 memmove(new_data, old_data, old_size);
63 memset(&new_data[old_size], 0, (data_size_in_bytes_ - old_size));
64 data_.ptr_ = new_data;
65 }
66 ASSERT(InBackingStore(bit_offset));
67 }
68
69 // Set bit if in backing store.
70 if (InBackingStore(bit_offset)) {
71 SetBit(bit_offset, value);
72 }
73}
74
75void BitmapBuilder::SetRange(intptr_t min, intptr_t max, bool value) {
76 for (intptr_t i = min; i <= max; i++) {
77 Set(i, value);
78 }
79}
80
82 for (intptr_t i = 0; i < Length(); i++) {
83 if (Get(i)) {
84 THR_Print("1");
85 } else {
86 THR_Print("0");
87 }
88 }
89}
90
92 // Early return if there are no bits in the payload to copy.
93 if (Length() == 0) return;
94
95 const intptr_t total_size =
97 intptr_t payload_size;
98 intptr_t extra_size;
99 if (total_size > data_size_in_bytes_) {
100 // A [BitmapBuilder] does not allocate storage for the trailing 0 bits in
101 // the backing store, so we need to add additional empty bytes here.
102 payload_size = data_size_in_bytes_;
103 extra_size = total_size - data_size_in_bytes_;
104 } else {
105 payload_size = total_size;
106 extra_size = 0;
107 }
108#if defined(DEBUG)
109 // Make sure any bits in the payload beyond the bit length if we're not
110 // appending trailing zeroes are cleared to ensure deterministic snapshots.
111 if (extra_size == 0 && Length() % kBitsPerByte != 0) {
112 const int8_t mask = (1 << (Length() % kBitsPerByte)) - 1;
113 ASSERT_EQUAL(BackingStore()[payload_size - 1],
114 (BackingStore()[payload_size - 1] & mask));
115 }
116#endif
117 stream->WriteBytes(BackingStore(), payload_size);
118 for (intptr_t i = 0; i < extra_size; i++) {
119 stream->WriteByte(0U);
120 }
121}
122
123bool BitmapBuilder::GetBit(intptr_t bit_offset) const {
124 if (!InRange(bit_offset)) {
125 return false;
126 }
127 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
128 ASSERT(byte_offset < data_size_in_bytes_);
129 intptr_t bit_remainder = bit_offset & (kBitsPerByte - 1);
130 uint8_t mask = 1U << bit_remainder;
131 return ((BackingStore()[byte_offset] & mask) != 0);
132}
133
134void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) {
135 if (!InRange(bit_offset)) {
136 FATAL(
137 "Fatal error in BitmapBuilder::SetBit :"
138 " invalid bit_offset, %" Pd "\n",
139 bit_offset);
140 }
141 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
142 ASSERT(byte_offset < data_size_in_bytes_);
143 intptr_t bit_remainder = bit_offset & (kBitsPerByte - 1);
144 uint8_t mask = 1U << bit_remainder;
145 if (value) {
146 BackingStore()[byte_offset] |= mask;
147 } else {
148 BackingStore()[byte_offset] &= ~mask;
149 }
150}
151
153 const intptr_t payload_size =
155 data_size_in_bytes_);
156 stream->Write<intptr_t>(Length());
157 stream->Write<intptr_t>(payload_size);
158 stream->WriteBytes(BackingStore(), payload_size);
159}
160
162 length_ = stream->Read<intptr_t>();
163 const intptr_t payload_size = stream->Read<intptr_t>();
164 if (payload_size > data_size_in_bytes_) {
165 data_size_in_bytes_ = payload_size;
166 data_.ptr_ = AllocBackingStore(data_size_in_bytes_);
167 } else {
168 memset(BackingStore() + payload_size, 0,
169 data_size_in_bytes_ - payload_size);
170 }
171 stream->ReadBytes(BackingStore(), payload_size);
172}
173
174} // namespace dart
static size_t total_size(SkSBlockAllocator< N > &pool)
#define ASSERT_EQUAL(expected, actual)
Definition: assert.h:309
void AppendAsBytesTo(BaseWriteStream *stream) const
Definition: bitmap.cc:91
void Read(ReadStream *stream)
Definition: bitmap.cc:161
void Write(BaseWriteStream *stream) const
Definition: bitmap.cc:152
bool Get(intptr_t bit_offset) const
Definition: bitmap.cc:35
void Set(intptr_t bit_offset, bool value)
Definition: bitmap.cc:44
intptr_t Length() const
Definition: bitmap.h:36
void Print() const
Definition: bitmap.cc:81
void SetRange(intptr_t min, intptr_t max, bool value)
Definition: bitmap.cc:75
void SetLength(intptr_t length)
Definition: bitmap.cc:13
static T Minimum(T x, T y)
Definition: utils.h:36
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
Definition: utils.h:120
#define THR_Print(format,...)
Definition: log.h:20
#define ASSERT(E)
#define FATAL(error)
uint8_t value
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
Definition: dart_vm.cc:33
constexpr intptr_t kBitsPerByteLog2
Definition: globals.h:462
constexpr intptr_t kBitsPerByte
Definition: globals.h:463
#define Pd
Definition: globals.h:408