// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_BASE_ADDRESS_REGION_H_ #define V8_BASE_ADDRESS_REGION_H_ #include <iostream> #include "src/base/macros.h" namespace v8 { namespace base { // Helper class representing an address region of certain size. class AddressRegion { public: // Function object that compares the start address of two regions. Usable as // compare function on std data structures and algorithms. struct StartAddressLess { bool operator()(base::AddressRegion a, base::AddressRegion b) const { return a.begin() < b.begin(); } }; using Address = uintptr_t; constexpr AddressRegion() = default; constexpr AddressRegion(Address address, size_t size) : address_(address), size_(size) {} Address begin() const { return address_; } Address end() const { return address_ + size_; } size_t size() const { return size_; } void set_size(size_t size) { size_ = size; } bool is_empty() const { return size_ == 0; } bool contains(Address address) const { STATIC_ASSERT(std::is_unsigned<Address>::value); return (address - begin()) < size(); } bool contains(Address address, size_t size) const { STATIC_ASSERT(std::is_unsigned<Address>::value); Address offset = address - begin(); return (offset < size_) && (offset + size <= size_); } bool contains(AddressRegion region) const { return contains(region.address_, region.size_); } base::AddressRegion GetOverlap(AddressRegion region) const { Address overlap_start = std::max(begin(), region.begin()); Address overlap_end = std::max(overlap_start, std::min(end(), region.end())); return {overlap_start, overlap_end - overlap_start}; } bool operator==(AddressRegion other) const { return address_ == other.address_ && size_ == other.size_; } bool operator!=(AddressRegion other) const { return address_ != other.address_ || size_ != other.size_; } private: Address address_ = 0; size_t size_ = 0; }; ASSERT_TRIVIALLY_COPYABLE(AddressRegion); // Construct an AddressRegion from anything providing a {data()} and {size()} // accessor. template <typename Container, typename = decltype(std::declval<Container>().data()), typename = decltype(std::declval<Container>().size())> inline constexpr AddressRegion AddressRegionOf(Container&& c) { return AddressRegion{reinterpret_cast<AddressRegion::Address>(c.data()), sizeof(*c.data()) * c.size()}; } inline std::ostream& operator<<(std::ostream& out, AddressRegion region) { return out << "[" << reinterpret_cast<void*>(region.begin()) << "+" << region.size() << "]"; } } // namespace base } // namespace v8 #endif // V8_BASE_ADDRESS_REGION_H_