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 Region.h 22 Contiguous range of subzones. 23 Copyright (c) 2004-2011 Apple Inc. All rights reserved. 24 */ 25 26#pragma once 27#ifndef __AUTO_REGION__ 28#define __AUTO_REGION__ 29 30#include "Admin.h" 31#include "Configuration.h" 32#include "Definitions.h" 33#include "Range.h" 34#include "Statistics.h" 35#include "Locks.h" 36 37namespace Auto { 38 39 // Forward declarations 40 41 class Zone; 42 class Subzone; 43 44 45 //----- Region -----// 46 47 class Region : public Range { 48 49 private: 50 51 Region *_next; // next region in the list. 52 Zone *_zone; // reference back to main zone 53 spin_lock_t _subzone_lock; // protects add_subzone(). 54 usword_t _i_subzones; // number of active subzones 55 usword_t _n_subzones; // total number of subzones 56 usword_t _n_quantum; // total number of quantum avalable 57 Range _scan_space; // space used during scanning - may be used as 58 // a stack or pending bits 59 Bitmap _pending; // "ready to use" bitmap overlayed on _scan_space 60 Bitmap _marks; // bitmap for the marks used during reachability analysis 61 Bitmap _pinned; // bitmap for compaction 62 63 public: 64 65 // 66 // bytes_needed 67 // 68 // Return the number of bytes needed to represent a region object of the specified size. 69 // 70 static const usword_t bytes_needed() { 71 return align2(sizeof(Region), page_size_log2); 72 } 73 74 // 75 // managed_size 76 // 77 // Return the number of bytes needed for N subzones. 78 // 79 static usword_t managed_size(usword_t nsubzones) { return (nsubzones << subzone_quantum_log2) + nsubzones * bitmaps_per_region * subzone_bitmap_bytes; } 80 81 // 82 // allocator 83 // 84 inline void *operator new(const size_t size) { 85 // allocate admin data 86 return allocate_memory(Region::bytes_needed()); 87 } 88 89 90 91 // 92 // deallocator 93 // 94 inline void operator delete(void *address) { 95 Region *region = (Region *)address; 96 97 // release subzone memory 98 // XXX region->_zone->arena_deallocate(region->address(), region->size()); 99 100 // release C++ "Region::" data structure, including admin data 101 deallocate_memory(region, Region::bytes_needed()); 102 } 103 104 105 // 106 // Constructor 107 // 108 Region(Zone *zone, void *address, usword_t size, usword_t nzones); 109 110 111 // 112 // Destructor 113 // 114 ~Region(); 115 116 117 // 118 // Accessors 119 // 120 inline void set_next(Region *next) { _next = next; } 121 inline Region *next() const { return _next; } 122 inline Zone *zone() const { return _zone; } 123 inline Range scan_space() const { return _scan_space; } 124 inline spin_lock_t *subzone_lock() { return &_subzone_lock; } 125 126 inline Bitmap &pending() { return _pending; } 127 inline Bitmap &marks() { return _marks; } 128 inline Bitmap &pinned() { return _pinned; } 129 130 // 131 // 132 // number of subzones remaining 133 // 134 inline usword_t subzones_remaining() const { return _n_subzones - _i_subzones; } 135 136 inline usword_t active_subzones() const { return _i_subzones; } 137 138 // 139 // new_region 140 // 141 // Construct and initialize a new region. 142 // 143 static Region *new_region(Zone *zone ); 144 145 // 146 // subzone_index 147 // 148 // Returns a regional subzone index for an arbitrary pointer. Note that this is relative to region memory. subzone_index in 149 // Zone is absolute memory. 150 // 151 inline const usword_t subzone_index(void *address) const { return (const usword_t)((uintptr_t)relative_address(address) >> subzone_quantum_log2); } 152 153 154 // 155 // subzone_size 156 // 157 // Returns the size of n subzones. 158 // 159 static inline usword_t subzone_size(const usword_t n) { return n << subzone_quantum_log2; } 160 161 162 // 163 // subzone_count 164 // 165 // Returns a number of subzone quantum for a given size. 166 // 167 static inline usword_t subzone_count(const size_t size) { return partition2(size, subzone_quantum_log2); } 168 169 170 // 171 // subzone_address 172 // 173 // Returns the address of the ith subzone 174 // 175 inline Subzone *subzone_address(const usword_t i) const { return (Subzone *)displace(address(), i << subzone_quantum_log2); } 176 177 178 // 179 // subzone_range 180 // 181 // Returns the range of active subzones. 182 // 183 inline Range subzone_range() { SpinLock lock(&_subzone_lock); return Range(address(), subzone_size(_i_subzones)); } 184 185 186 // 187 // add_subzone 188 // 189 // Add a new subzone to one of the admin. 190 // 191 bool add_subzone(Admin *admin); 192 193 194 // 195 // test_and_set_mark 196 // 197 // Used by subzone to test and set mark bit for quantum. 198 // 199 inline bool test_and_set_mark(usword_t q) { 200 return (bool)_marks.test_set_bit_atomic(q); 201 } 202 203 204 // 205 // test_and_clear_mark 206 // 207 // Used by subzone to test and clear mark bit for quantum. 208 // 209 inline bool test_and_clear_mark(usword_t q) { 210 return (bool)_marks.test_clear_bit_atomic(q); 211 } 212 213 214 // 215 // clear_marks 216 // 217 // Used at the end of collection 218 // 219 inline void clear_marks() { 220 _marks.clear(); 221 } 222 }; 223 224 225}; 226 227 228#endif // __AUTO_REGION__ 229