1/* 2 * Copyright (c) 2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20/* 21 Range.h 22 Contiguous Address Range 23 Copyright (c) 2004-2011 Apple Inc. All rights reserved. 24 */ 25 26#pragma once 27#ifndef __AUTO_RANGE__ 28#define __AUTO_RANGE__ 29 30 31#include "Definitions.h" 32 33 34namespace Auto { 35 36 //----- Range -----// 37 38 // 39 // Manage an area of memory 40 // 41 42 class Range { 43 44 private: 45 46 void *_address; // start of range 47 void *_end; // end of the range (one byte beyond last usable space) 48 49 public: 50 51 // 52 // Constructors 53 // 54 Range() : _address(NULL), _end(NULL) {} 55 Range(void *address) : _address(address), _end(address) {} 56 Range(void *address, void *end) : _address(address), _end(end) {} 57 Range(void *address, usword_t size) : _address(address), _end(displace(address, size)) {} 58 59 60 // 61 // Accessors 62 // 63 inline Range& range() { return *this; } 64 inline void *address() const { return _address; } 65 inline void *end() const { return _end; } 66 inline const usword_t size() const { return (uintptr_t)_end - (uintptr_t)_address; } 67 inline void set_address(void *address) { _address = address; } 68 inline void set_end(void *end) { _end = end; } 69 inline void set_size(usword_t size) { _end = displace(_address, size); } 70 inline void set_range(void *address, void *end) { _address = address; _end = end; } 71 inline void set_range(void *address, usword_t size) { _address = address; _end = displace(address, size); } 72 inline void set_range(Range range) { _address = range.address(); _end = range.end(); } 73 inline void adjust_address(intptr_t delta) { _address = displace(_address, delta); } 74 inline void adjust_end(intptr_t delta) { _end = displace(_end, delta); } 75 inline void adjust(intptr_t delta) { _address = displace(_address, delta), _end = displace(_end, delta); } 76 77 78 // 79 // is_empty 80 // 81 // Returns true if the range is empty. 82 // 83 inline bool is_empty() { return _address == _end; } 84 85 86 // 87 // in_range 88 // 89 // Returns true if the specified address is in range. 90 // This form reduces the number of branches. Works well with invariant lo and hi. 91 // 92 static inline const bool in_range(void *lo, void *hi, void *address) { 93 uintptr_t lo_as_int = (uintptr_t)lo; 94 uintptr_t hi_as_int = (uintptr_t)hi; 95 uintptr_t diff = hi_as_int - lo_as_int; 96 uintptr_t address_as_int = (uintptr_t)address; 97 return (address_as_int - lo_as_int) < diff; 98 } 99 inline const bool in_range(void *address) const { return in_range(_address, _end, address); } 100 101 102 // 103 // operator == 104 // 105 // Used to locate entry in list or hash table (use is_range for exaxt match.) 106 inline const bool operator==(const Range *range) const { return _address == range->_address; } 107 inline const bool operator==(const Range &range) const { return _address == range._address; } 108 109 // 110 // is_range 111 // 112 // Return true if the ranges are equivalent. 113 // 114 inline const bool is_range(const Range& range) const { return _address == range._address && _end == range._end; } 115 116 117 // 118 // clear 119 // 120 // Initialize the range to zero. 121 // 122 inline void clear() { bzero(address(), size()); } 123 124 // 125 // uncommit 126 // 127 // Tell the operating system the contents of the pages can be purged. 128 // 129 inline void uncommit() { uncommit_memory(address(), size()); } 130 131 // 132 // commit 133 // 134 // Tell the operating system the pages in this range are about to be reused. 135 // 136 inline void commit() { commit_memory(address(), size()); } 137 138 // 139 // expand_range 140 // 141 // Expand the bounds with the specified range. 142 // 143 inline void expand_range(void *address) { 144 if (_address > address) _address = address; 145 if (_end < address) _end = address; 146 } 147 inline void expand_range(Range& range) { 148 expand_range(range.address()); 149 expand_range(range.end()); 150 } 151 152 153 // 154 // relative_address 155 // 156 // Converts an absolute address to an address relative to this address. 157 // 158 inline void *relative_address(void *address) const { return (void *)((uintptr_t)address - (uintptr_t)_address); } 159 160 161 // 162 // absolute_address 163 // 164 // Converts an address relative to this address to an absolute address. 165 // 166 inline void *absolute_address(void *address) const { return (void *)((uintptr_t)address + (uintptr_t)_address); } 167 168 169 }; 170 171}; 172 173#endif // __AUTO_RANGE__ 174 175