001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.mmtk.utility.gcspy; 014 015import org.mmtk.utility.Log; 016import org.mmtk.vm.gcspy.Util; 017 018import org.vmmagic.unboxed.*; 019import org.vmmagic.pragma.*; 020 021 022 023/** 024 * This class is an abstraction of a contiguous region of a Space. For 025 * example, a semispace collector might choose to model the heap as a 026 * single Space, but within that Space it could model each semispace by 027 * a Subspace.<p> 028 * Subspace provides a number of useful facilities to many drivers, and 029 * is useful even if the Space comprises just a single contiguous region.<p> 030 * 031 * A subspace keeps track of the start and end address of the region, 032 * the index of its first block, the size of the blocks in this space, 033 * and the number of blocks in this subspace. 034 */ 035@Uninterruptible public class Subspace { 036 037 /** start address of the subspace. A subspace spans the address 038 * range <code>[start_, end_)</code> **/ 039 private Address start_; 040 /** end address of the subspace. A subspace spans the address 041 * range <code>[start_, end_)</code> **/ 042 private Address end_; 043 /** The index of the block in which {@code start_} lies */ 044 private int firstIndex_; 045 /** the block size */ 046 private int blockSize_; 047 /** the number of blocks in this space */ 048 private int blockNum_; 049 050 private static final boolean DEBUG = false; 051 052 /** 053 * Create a new subspace 054 * 055 * @param start The address of the start of the subspace 056 * @param end The address of the end of the subspace 057 * @param firstIndex The index of the first block of the subspace 058 * @param blockSize The size of blocks in this space 059 * @param blockNum The number of blocks in this subspace 060 */ 061 public Subspace(Address start, 062 Address end, 063 int firstIndex, 064 int blockSize, 065 int blockNum) { 066 reset(start, end, firstIndex, blockSize, blockNum); 067 } 068 069 070 //------------------Methods to reset a subspace---------------------- 071 072 /** 073 * Reset a subspace. 074 * 075 * @param start The address of the start of the subspace 076 * @param end The address of the end of the subspace 077 * @param firstIndex The index of the first block of the subspace 078 * @param blockSize The size of blocks in this subspace 079 * @param blockNum The number of blocks in this subspace 080 */ 081 private void reset(Address start, 082 Address end, 083 int firstIndex, 084 int blockSize, 085 int blockNum) { 086 //TODO sanity check on addresses and block size and number 087 reset(start, end, firstIndex, blockNum); 088 blockSize_ = blockSize; 089 090 if (DEBUG) dump(); 091 } 092 093 /** 094 * Reset a new subspace 095 * 096 * @param start The address of the start of the subspace 097 * @param end The address of the end of the subspace 098 * @param firstIndex The index of the first block of the subspace 099 * @param blockNum The number of blocks in this subspace 100 */ 101 public void reset(Address start, 102 Address end, 103 int firstIndex, 104 int blockNum) { 105 start_ = start; 106 end_ = end; 107 firstIndex_ = firstIndex; 108 blockNum_ = blockNum; 109 } 110 111 /** 112 * Reset a new subspace. 113 * 114 * @param start The address of the start of the subspace 115 * @param end The address of the end of the subspace 116 * @param blockNum The number of blocks in this subspace 117 */ 118 public void reset(Address start, Address end, int blockNum) { 119 start_ = start; 120 end_ = end; 121 blockNum_ = blockNum; 122 } 123 124 /** 125 * Reset a new subspace. 126 * 127 * @param firstIndex The index of the first block of the subspace 128 * @param blockNum The number of blocks in this subspace 129 */ 130 public void reset(int firstIndex, int blockNum) { 131 firstIndex_ = firstIndex; 132 blockNum_ = blockNum; 133 } 134 135 136 //----------------Facilities to query a subspace----------------- 137 138 /** 139 * Is an index in the range of this subspace? 140 * 141 * @param index The index of the block 142 * @return {@code true} if this block lies in this subspace 143 */ 144 public boolean indexInRange(int index) { 145 return index >= firstIndex_ && 146 index < firstIndex_ + blockNum_; 147 } 148 149 /** 150 * Is address in the range of this subspace? 151 * 152 * @param addr An address 153 * @return {@code true} if this address is in a block in this subspace 154 */ 155 public boolean addressInRange(Address addr) { 156 return addr.GE(start_) && addr.LT(end_); 157 } 158 159 160 /** 161 * Get the block index from an address 162 * 163 * @param addr The address 164 * @return The index of the block holding this address 165 */ 166 public int getIndex(Address addr) { 167 if (DEBUG) { 168 Log.write("start_ ", start_); 169 Log.write(" end_ ", end_); 170 Log.write(" blockSize_ ", blockSize_); 171 Log.write(" firstIndex_ ", firstIndex_); 172 Log.write(" + ", addr.diff(start_).toInt() / blockSize_); 173 Log.writeln(" addr ", addr); 174 } 175 return firstIndex_ + addr.diff(start_).toInt() / blockSize_; 176 } 177 178 /** 179 * Get the address of start of block from its index 180 * 181 * @param index The index of the block 182 * @return The address of the start of the block 183 */ 184 public Address getAddress(int index) { 185 return start_.plus(index - firstIndex_ * blockSize_); 186 } 187 188 //--------------Accessors------------------------- 189 190 /** 191 * Get the start of the subspace 192 * @return The start of this subspace 193 */ 194 public Address getStart() { 195 return start_; 196 } 197 198 /** 199 * Get the end of this subspace 200 * @return The address of the end of this subspace 201 */ 202 public Address getEnd() { 203 return end_; 204 } 205 206 /** 207 * Get the first index of subspace 208 * @return the firstIndex of this subspace 209 */ 210 public int getFirstIndex() { 211 return firstIndex_; 212 } 213 214 /** 215 * Get the blocksize for this subspace 216 * @return The size of a tile 217 */ 218 public int getBlockSize() { 219 return blockSize_; 220 } 221 222 /** 223 * Get the number of tiles in this subspace 224 * @return The number of tiles in this subspace 225 */ 226 public int getBlockNum() { 227 return blockNum_; 228 } 229 230 /** 231 * Calculate the space remaining in a block after this address 232 * 233 * @param addr the Address 234 * @return the remainder 235 */ 236 public int spaceRemaining(Address addr) { 237 int nextIndex = getIndex(addr) + 1; 238 Address nextTile = start_.plus(blockSize_ * (nextIndex - firstIndex_)); 239 return nextTile.diff(addr).toInt(); 240 } 241 242 /** 243 * Dump a representation of the subspace 244 */ 245 private void dump() { 246 Log.write("GCspy Subspace: "); 247 Util.dumpRange(start_, end_); 248 Log.writeln("\n -- firstIndex=", firstIndex_); 249 Log.writeln(" -- blockNum=", blockNum_); 250 } 251} 252 253