// Memory regions are useful for accessing memory with bounds check in // debug mode. They can be safely passed by value and do not assume ownership // of the region. class MemoryRegion final : public ValueObject { public:
constexpr booloperator==(const MemoryRegion& other) const { return size() == other.size() && memcmp(begin(), other.begin(), size()) == 0;
}
// Load value of type `T` at `offset`. The memory address corresponding // to `offset` should be word-aligned (on ARM, this is a requirement). template<typename T>
ALWAYS_INLINE T Load(uintptr_t offset) const {
T* address = ComputeInternalPointer<T>(offset);
DCHECK(IsWordAligned(address)); return *address;
}
// Store `value` (of type `T`) at `offset`. The memory address // corresponding to `offset` should be word-aligned (on ARM, this is // a requirement). template<typename T>
ALWAYS_INLINE void Store(uintptr_t offset, T value) const {
T* address = ComputeInternalPointer<T>(offset);
DCHECK(IsWordAligned(address));
*address = value;
}
// Load value of type `T` at `offset`. The memory address corresponding // to `offset` does not need to be word-aligned. template<typename T>
ALWAYS_INLINE T LoadUnaligned(uintptr_t offset) const { // Equivalent unsigned integer type corresponding to T. using U = std::make_unsigned_t<T>;
U equivalent_unsigned_integer_value = 0; // Read the value byte by byte in a little-endian fashion. for (size_t i = 0; i < sizeof(U); ++i) {
equivalent_unsigned_integer_value +=
*ComputeInternalPointer<uint8_t>(offset + i) << (i * kBitsPerByte);
} return bit_cast<T, U>(equivalent_unsigned_integer_value);
}
// Store `value` (of type `T`) at `offset`. The memory address // corresponding to `offset` does not need to be word-aligned. template<typename T>
ALWAYS_INLINE void StoreUnaligned(uintptr_t offset, T value) const { // Equivalent unsigned integer type corresponding to T. using U = std::make_unsigned_t<T>;
U equivalent_unsigned_integer_value = bit_cast<U, T>(value); // Write the value byte by byte in a little-endian fashion. for (size_t i = 0; i < sizeof(U); ++i) {
*ComputeInternalPointer<uint8_t>(offset + i) =
(equivalent_unsigned_integer_value >> (i * kBitsPerByte)) & 0xFF;
}
}
// Locate the bit with the given offset. Returns a pointer to the byte // containing the bit, and sets bit_mask to the bit within that byte.
ALWAYS_INLINE uint8_t* ComputeBitPointer(uintptr_t bit_offset, uint8_t* bit_mask) const {
uintptr_t bit_remainder = (bit_offset & (kBitsPerByte - 1));
*bit_mask = (1U << bit_remainder);
uintptr_t byte_offset = (bit_offset >> kBitsPerByteLog2); return ComputeInternalPointer<uint8_t>(byte_offset);
}
// Is `address` aligned on a machine word? template<typename T> static constexpr bool IsWordAligned(const T* address) { // Word alignment in bytes. Determined from pointer size. return IsAligned<kRuntimePointerSize>(address);
}
void* pointer_;
size_t size_;
};
} // namespace art
#endif// ART_LIBARTBASE_BASE_MEMORY_REGION_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.