Flutter Engine
The Flutter Engine
bitfield.h
Go to the documentation of this file.
1// Copyright (c) 2011, 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#ifndef RUNTIME_VM_BITFIELD_H_
6#define RUNTIME_VM_BITFIELD_H_
7
8#include <type_traits>
9
10#include "platform/assert.h"
11#include "platform/atomic.h"
12#include "platform/globals.h"
14
15namespace dart {
16
18 private:
19 AtomicBitFieldContainerBase() = delete; // Only used for std::is_base_of.
20};
21
22template <typename T>
24 static_assert(sizeof(std::atomic<T>) == sizeof(T),
25 "Size of type changes when made atomic");
26
27 public:
29
30 AtomicBitFieldContainer() : field_(0) {}
31
32 operator T() const { return field_.load(std::memory_order_relaxed); }
33 T operator=(T tags) {
34 field_.store(tags, std::memory_order_relaxed);
35 return tags;
36 }
37
38 T load(std::memory_order order) const { return field_.load(order); }
40 return *reinterpret_cast<const T*>(&field_);
41 }
42 void store(T value, std::memory_order order) { field_.store(value, order); }
43
44 bool compare_exchange_weak(T old_tags, T new_tags, std::memory_order order) {
45 return field_.compare_exchange_weak(old_tags, new_tags, order);
46 }
47
48 template <class TargetBitField,
49 std::memory_order order = std::memory_order_relaxed>
50 typename TargetBitField::Type Read() const {
51 return TargetBitField::decode(field_.load(order));
52 }
53
54 template <class TargetBitField,
55 std::memory_order order = std::memory_order_relaxed>
56 void UpdateBool(bool value) {
57 if (value) {
58 field_.fetch_or(TargetBitField::encode(true), order);
59 } else {
60 field_.fetch_and(~TargetBitField::encode(true), order);
61 }
62 }
63
64 template <class TargetBitField>
66 field_.fetch_or(TargetBitField::encode(value), std::memory_order_relaxed);
67 }
68
69 template <class TargetBitField>
71 T old_field = field_.load(std::memory_order_relaxed);
72 T new_field;
73 do {
74 new_field = TargetBitField::update(value, old_field);
75 } while (!field_.compare_exchange_weak(old_field, new_field,
76 std::memory_order_relaxed));
77 }
78
79 template <class TargetBitField>
81 field_.store(
82 TargetBitField::update(value, field_.load(std::memory_order_relaxed)),
83 std::memory_order_relaxed);
84 }
85
86 template <class TargetBitField>
88 typename TargetBitField::Type value_to_be_set,
89 typename TargetBitField::Type conditional_old_value) {
90 T old_field = field_.load(std::memory_order_relaxed);
91 while (true) {
92 // This operation is only performed if the condition is met.
93 auto old_value = TargetBitField::decode(old_field);
94 if (old_value != conditional_old_value) {
95 return old_value;
96 }
97 T new_tags = TargetBitField::update(value_to_be_set, old_field);
98 if (field_.compare_exchange_weak(old_field, new_tags,
99 std::memory_order_relaxed)) {
100 return value_to_be_set;
101 }
102 // [old_tags] was updated to it's current value.
103 }
104 }
105
106 template <class TargetBitField>
107 bool TryAcquire() {
108 T mask = TargetBitField::encode(true);
109 T old_field = field_.fetch_or(mask, std::memory_order_relaxed);
110 return !TargetBitField::decode(old_field);
111 }
112
113 template <class TargetBitField>
114 bool TryClear() {
115 T mask = ~TargetBitField::encode(true);
116 T old_field = field_.fetch_and(mask, std::memory_order_relaxed);
117 return TargetBitField::decode(old_field);
118 }
119
120 private:
121 std::atomic<T> field_;
122};
123
124static constexpr uword kUwordOne = 1U;
125
126// BitField is a template for encoding and decoding a value of type T
127// inside a storage of type S.
128template <typename S,
129 typename T,
130 int position,
131 int size = (sizeof(S) * kBitsPerByte) - position,
132 bool sign_extend = false,
133 typename Enable = void>
134class BitField {
135 public:
136 typedef T Type;
137
138 static_assert((sizeof(S) * kBitsPerByte) >= (position + size),
139 "BitField does not fit into the type.");
140 static_assert(!sign_extend || std::is_signed<T>::value,
141 "Should only sign extend signed bitfield types");
142
143 static constexpr intptr_t kNextBit = position + size;
144
145 // Tells whether the provided value fits into the bit field.
146 static constexpr bool is_valid(T value) {
147 return decode(encode_unchecked(value)) == value;
148 }
149
150 // Returns a S mask of the bit field.
151 static constexpr S mask() { return (kUwordOne << size) - 1; }
152
153 // Returns a S mask of the bit field which can be applied directly to
154 // to the raw unshifted bits.
155 static constexpr S mask_in_place() { return mask() << position; }
156
157 // Returns the shift count needed to right-shift the bit field to
158 // the least-significant bits.
159 static constexpr int shift() { return position; }
160
161 // Returns the size of the bit field.
162 static constexpr int bitsize() { return size; }
163
164 // Returns an S with the bit field value encoded.
165 static constexpr S encode(T value) {
167 return encode_unchecked(value);
168 }
169
170 // Extracts the bit field from the value.
171 static constexpr T decode(S value) {
172 // Ensure we slide down the sign bit if the value in the bit field is signed
173 // and negative. We use 64-bit ints inside the expression since we can have
174 // both cases: sizeof(S) > sizeof(T) or sizeof(S) < sizeof(T).
175 if constexpr (sign_extend) {
176 auto const u = static_cast<uint64_t>(value);
177 return static_cast<T>((static_cast<int64_t>(u << (64 - kNextBit))) >>
178 (64 - size));
179 } else {
180 auto const u = static_cast<typename std::make_unsigned<S>::type>(value);
181 return static_cast<T>((u >> position) & mask());
182 }
183 }
184
185 // Returns an S with the bit field value encoded based on the
186 // original value. Only the bits corresponding to this bit field
187 // will be changed.
188 static constexpr S update(T value, S original) {
189 return encode(value) | (~mask_in_place() & original);
190 }
191
192 private:
193 // Returns an S with the bit field value encoded.
194 static constexpr S encode_unchecked(T value) {
195 auto const u = static_cast<typename std::make_unsigned<S>::type>(value);
196 return (u & mask()) << position;
197 }
198};
199
200// Partial instantiations to avoid having to change BitField declarations if
201// S is decltype(field_) and the type of field_ is changed to be wrapped in an
202// AtomicBitFieldContainer.
203template <typename S, typename T, int position, int size, bool sign_extend>
205 T,
206 position,
207 size,
209 typename std::enable_if<
210 std::is_base_of<AtomicBitFieldContainerBase, S>::value,
211 void>::type> : public BitField<typename S::ContainedType,
212 T,
213 position,
214 size,
215 sign_extend> {};
216
217template <typename S, typename T, int position, int size>
219 T,
220 position,
221 size,
222 false,
223 typename std::enable_if<
224 std::is_base_of<AtomicBitFieldContainerBase, S>::value,
225 void>::type>
226 : public BitField<typename S::ContainedType, T, position, size, false> {};
227
228} // namespace dart
229
230#endif // RUNTIME_VM_BITFIELD_H_
static void encode(uint8_t output[16], const uint32_t input[4])
Definition: SkMD5.cpp:240
Type
Definition: SortBench.cpp:56
GLenum type
void UpdateBool(bool value)
Definition: bitfield.h:56
void FetchOr(typename TargetBitField::Type value)
Definition: bitfield.h:65
TargetBitField::Type UpdateConditional(typename TargetBitField::Type value_to_be_set, typename TargetBitField::Type conditional_old_value)
Definition: bitfield.h:87
void UpdateUnsynchronized(typename TargetBitField::Type value)
Definition: bitfield.h:80
bool compare_exchange_weak(T old_tags, T new_tags, std::memory_order order)
Definition: bitfield.h:44
NO_SANITIZE_THREAD T load_ignore_race() const
Definition: bitfield.h:39
void store(T value, std::memory_order order)
Definition: bitfield.h:42
void Update(typename TargetBitField::Type value)
Definition: bitfield.h:70
T load(std::memory_order order) const
Definition: bitfield.h:38
TargetBitField::Type Read() const
Definition: bitfield.h:50
static constexpr int bitsize()
Definition: bitfield.h:162
static constexpr intptr_t kNextBit
Definition: bitfield.h:143
static constexpr T decode(S value)
Definition: bitfield.h:171
static constexpr S update(T value, S original)
Definition: bitfield.h:188
static constexpr S mask_in_place()
Definition: bitfield.h:155
static constexpr S mask()
Definition: bitfield.h:151
static constexpr S encode(T value)
Definition: bitfield.h:165
static constexpr bool is_valid(T value)
Definition: bitfield.h:146
static constexpr int shift()
Definition: bitfield.h:159
#define ASSERT(E)
uint8_t value
Definition: dart_vm.cc:33
constexpr intptr_t kBitsPerByte
Definition: globals.h:463
uintptr_t uword
Definition: globals.h:501
intx_t sign_extend(int32_t x)
static constexpr uword kUwordOne
Definition: bitfield.h:124
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
Definition: ref_ptr.h:256
static DecodeResult decode(std::string path)
Definition: png_codec.cpp:124
#define T
Definition: precompiler.cc:65
#define NO_SANITIZE_THREAD