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.vm; 014 015import org.mmtk.utility.options.Options; 016import org.mmtk.utility.gcspy.Color; 017import org.mmtk.utility.gcspy.drivers.AbstractDriver; 018import org.mmtk.vm.gcspy.ByteStream; 019import org.mmtk.vm.gcspy.IntStream; 020import org.mmtk.vm.gcspy.ServerInterpreter; 021import org.mmtk.vm.gcspy.ServerSpace; 022import org.mmtk.vm.gcspy.ShortStream; 023import org.mmtk.vm.gcspy.Util; 024import org.vmmagic.pragma.Untraced; 025import org.vmmagic.unboxed.Address; 026import org.vmmagic.unboxed.Offset; 027 028/** 029 * This class is responsible for all VM-specific functionality required 030 * by MMTk.<p> 031 * 032 * The class has three major elements. First it defines VM-specific 033 * constants which are used throughout MMTk, second, it declares 034 * singleton instances of each of the abstract classes in this 035 * package, and third, it provides factory methods for VM-specific 036 * instances which are needed by MMTk (such as <code>Lock</code>).<p> 037 * 038 * Both the constants and the singleton instances are initialized to 039 * VM-specific values at build time using reflection and a VM-specific 040 * factory class. The system property <code>mmtk.hostjvm</code> is 041 * interrogated at build time to establish concrete instantations of 042 * the abstract classes in this package. By <b>convention</b>, 043 * <code>mmtk.hostjvm</code> will identify a VM-provided package which 044 * includes concrete instances of each of the abstract classes, with 045 * each concrete class having the same base class name (but different 046 * package name) as the abstract classes defined here. The class 047 * initializer for this class then uses the system property 048 * <code>mmtk.hostjvm</code> to load the VM-specific concrete classes 049 * and initialize the constants and singletons defined here. 050 */ 051public final class VM { 052 /* 053 * VM-specific constant values 054 */ 055 056 /** <code>true</code> if assertions should be verified */ 057 public static final boolean VERIFY_ASSERTIONS; 058 /** The lowest address in virtual memory known to MMTk */ 059 public static final Address HEAP_START; 060 /** The highest address in virtual memory known to MMTk */ 061 public static final Address HEAP_END; 062 /** The lowest address in the contiguously available memory available to MMTk */ 063 public static final Address AVAILABLE_START; 064 /** The highest address in the contiguously available memory available to MMTk */ 065 public static final Address AVAILABLE_END; 066 /** The log base two of the size of an address */ 067 public static final byte LOG_BYTES_IN_ADDRESS; 068 /** The log base two of the size of a word */ 069 public static final byte LOG_BYTES_IN_WORD; 070 /** The log base two of the size of an OS page */ 071 public static final byte LOG_BYTES_IN_PAGE; 072 /** The log base two of the minimum allocation alignment */ 073 public static final byte LOG_MIN_ALIGNMENT; 074 /** The log base two of (MAX_ALIGNMENT/MIN_ALIGNMENT) */ 075 public static final byte MAX_ALIGNMENT_SHIFT; 076 /** The maximum number of bytes of padding to prepend to an object */ 077 public static final int MAX_BYTES_PADDING; 078 /** The value to store in alignment holes */ 079 public static final int ALIGNMENT_VALUE; 080 /** The offset from an array reference to element zero */ 081 public static final Offset ARRAY_BASE_OFFSET; 082 /** Global debugging switch */ 083 public static final boolean DEBUG; 084 085 /** Exit code to pass if reflection for querying or creating important objects fails. */ 086 public static final int EXIT_CODE_REFLECTION_FAILURE = 2; 087 088 /* 089 * VM-specific functionality captured in a series of singleton classs 090 */ 091 @Untraced 092 public static final ActivePlan activePlan; 093 @Untraced 094 public static final Assert assertions; 095 @Untraced 096 public static final Barriers barriers; 097 @Untraced 098 public static final Collection collection; 099 @Untraced 100 public static final Config config; 101 @Untraced 102 public static final Memory memory; 103 @Untraced 104 public static final ObjectModel objectModel; 105 @Untraced 106 public static final ReferenceProcessor weakReferences; 107 @Untraced 108 public static final ReferenceProcessor softReferences; 109 @Untraced 110 public static final ReferenceProcessor phantomReferences; 111 @Untraced 112 public static final FinalizableProcessor finalizableProcessor; 113 @Untraced 114 public static final Scanning scanning; 115 @Untraced 116 public static final Statistics statistics; 117 @Untraced 118 public static final Strings strings; 119 @Untraced 120 public static final TraceInterface traceInterface; 121 @Untraced 122 public static final MMTk_Events events; 123 @Untraced 124 public static final Debug debugging; 125 126 /* 127 * The remainder is does the static initialization of the 128 * above, reflectively binding to the appropriate host jvm 129 * classes. 130 */ 131 private static final Factory factory; 132 private static final String vmFactory; 133 134 /** 135 * This class initializer establishes a VM-specific factory class 136 * using reflection, and then uses that to create VM-specific concrete 137 * instances of all of the vm classes, initializing the singltons in 138 * this class. Finally the constants declared in this class are 139 * initialized using the VM-specific singletons. 140 */ 141 static { 142 /* Identify the VM-specific factory using reflection */ 143 vmFactory = System.getProperty("mmtk.hostjvm"); 144 Factory xfa = null; 145 try { 146 xfa = (Factory) Class.forName(vmFactory).newInstance(); 147 } catch (Exception e) { 148 e.printStackTrace(); 149 System.exit(EXIT_CODE_REFLECTION_FAILURE); // we must *not* go on if the above has failed 150 } 151 factory = xfa; 152 153 /* Now instantiate the singletons using the factory */ 154 activePlan = factory.newActivePlan(); 155 assertions = factory.newAssert(); 156 barriers = factory.newBarriers(); 157 collection = factory.newCollection(); 158 memory = factory.newMemory(); 159 objectModel = factory.newObjectModel(); 160 Options.set = factory.getOptionSet(); 161 weakReferences = factory.newReferenceProcessor(ReferenceProcessor.Semantics.WEAK); 162 softReferences = factory.newReferenceProcessor(ReferenceProcessor.Semantics.SOFT); 163 phantomReferences = factory.newReferenceProcessor(ReferenceProcessor.Semantics.PHANTOM); 164 finalizableProcessor = factory.newFinalizableProcessor(); 165 scanning = factory.newScanning(); 166 statistics = factory.newStatistics(); 167 strings = factory.newStrings(); 168 traceInterface = factory.newTraceInterface(); 169 events = factory.newEvents(); 170 debugging = factory.newDebug(); 171 config = new Config(factory.newBuildTimeConfig()); 172 173 /* Now initialize the constants using the vm-specific singletons */ 174 VERIFY_ASSERTIONS = Assert.verifyAssertionsTrapdoor(assertions); 175 HEAP_START = Memory.heapStartTrapdoor(memory); 176 HEAP_END = Memory.heapEndTrapdoor(memory); 177 AVAILABLE_START = Memory.availableStartTrapdoor(memory); 178 AVAILABLE_END = Memory.availableEndTrapdoor(memory); 179 LOG_BYTES_IN_ADDRESS = Memory.logBytesInAddressTrapdoor(memory); 180 LOG_BYTES_IN_WORD = Memory.logBytesInWordTrapdoor(memory); 181 LOG_BYTES_IN_PAGE = Memory.logBytesInPageTrapdoor(memory); 182 LOG_MIN_ALIGNMENT = Memory.logMinAlignmentTrapdoor(memory); 183 MAX_ALIGNMENT_SHIFT = Memory.maxAlignmentShiftTrapdoor(memory); 184 MAX_BYTES_PADDING = Memory.maxBytesPaddingTrapdoor(memory); 185 ALIGNMENT_VALUE = Memory.alignmentValueTrapdoor(memory); 186 ARRAY_BASE_OFFSET = ObjectModel.arrayBaseOffsetTrapdoor(objectModel); 187 DEBUG = Debug.isEnabledTrapdoor(debugging); 188 } 189 190 /** 191 * Create a new Lock instance using the appropriate VM-specific 192 * concrete Lock sub-class. 193 * 194 * @see Lock 195 * 196 * @param name The string to be associated with this lock instance 197 * @return A concrete VM-specific Lock instance. 198 */ 199 public static Lock newLock(String name) { 200 return factory.newLock(name); 201 } 202 203 /** 204 * Create a new HeavyCondLock instance using the appropriate VM-specific 205 * concrete Lock sub-class. 206 * 207 * @see Monitor 208 * 209 * @param name The string to be associated with this instance 210 * @return A concrete VM-specific HeavyCondLock instance. 211 */ 212 public static Monitor newHeavyCondLock(String name) { 213 return factory.newMonitor(name); 214 } 215 216 /** 217 * Create a new SynchronizedCounter instance using the appropriate 218 * VM-specific concrete SynchronizedCounter sub-class. 219 * 220 * @see SynchronizedCounter 221 * 222 * @return A concrete VM-specific SynchronizedCounter instance. 223 */ 224 public static SynchronizedCounter newSynchronizedCounter() { 225 return factory.newSynchronizedCounter(); 226 } 227 228 /********************************************************************** 229 * GCspy methods 230 */ 231 232 /** 233 * Create a new Util instance using the appropriate 234 * VM-specific concrete Util sub-class. 235 * 236 * @see Util 237 * 238 * @return A concrete VM-specific Util instance. 239 */ 240 public static Util newGCspyUtil() { 241 return factory.newGCspyUtil(); 242 } 243 244 /** 245 * Create a new ServerInterpreter instance using the appropriate 246 * VM-specific concrete ServerInterpreter sub-class. 247 * 248 * @see ServerInterpreter 249 * 250 * @return A concrete VM-specific ServerInterpreter instance. 251 */ 252 public static ServerInterpreter newGCspyServerInterpreter() { 253 return factory.newGCspyServerInterpreter(); 254 } 255 256 /** 257 * Create a new ServerSpace instance using the appropriate VM-specific 258 * concrete ServerSpace sub-class. 259 * 260 * @param serverInterpreter The server that owns this space 261 * @param serverName The server's name 262 * @param driverName The space driver's name 263 * @param title Title for the space 264 * @param blockInfo A label for each block 265 * @param tileNum Max number of tiles in this space 266 * @param unused A label for unused blocks 267 * @param mainSpace Whether this space is the main space 268 * 269 * @see ServerSpace 270 * @return A concrete VM-specific ServerSpace instance. 271 */ 272 public static ServerSpace newGCspyServerSpace( 273 ServerInterpreter serverInterpreter, 274 String serverName, 275 String driverName, 276 String title, 277 String blockInfo, 278 int tileNum, 279 String unused, 280 boolean mainSpace) { 281 return factory.newGCspyServerSpace(serverInterpreter, serverName, driverName, 282 title, blockInfo, tileNum, unused, 283 mainSpace); 284 } 285 286 /** 287 * Create a new ByteStream instance using the appropriate 288 * VM-specific concrete ByteStream sub-class. 289 * 290 * @param driver The driver that owns this Stream 291 * @param name The name of the stream (e.g. "Used space") 292 * @param minValue The minimum value for any item in this stream. 293 * Values less than this will be represented as "minValue-" 294 * @param maxValue The maximum value for any item in this stream. 295 * Values greater than this will be represented as "maxValue+" 296 * @param zeroValue The zero value for this stream 297 * @param defaultValue The default value for this stream 298 * @param stringPre A string to prefix values (e.g. "Used: ") 299 * @param stringPost A string to suffix values (e.g. " bytes.") 300 * @param presentation How a stream value is to be presented. 301 * @param paintStyle How the value is to be painted. 302 * @param indexMaxStream The index of the maximum stream if the presentation is *_VAR. 303 * @param colour The default colour for tiles of this stream 304 * @param summary Is a summary enabled? 305 * @see IntStream 306 * 307 * @return A concrete VM-specific ByteStream instance. 308 */ 309 public static ByteStream newGCspyByteStream( 310 AbstractDriver driver, 311 String name, 312 byte minValue, 313 byte maxValue, 314 byte zeroValue, 315 byte defaultValue, 316 String stringPre, 317 String stringPost, 318 int presentation, 319 int paintStyle, 320 int indexMaxStream, 321 Color colour, 322 boolean summary) { 323 return factory.newGCspyByteStream(driver, name, minValue, maxValue, 324 zeroValue, defaultValue, stringPre, stringPost, 325 presentation, paintStyle, indexMaxStream, 326 colour, summary); 327 } 328 329 /** 330 * Create a new IntStream instance using the appropriate 331 * VM-specific concrete IntStream sub-class. 332 * 333 * @param driver The driver that owns this Stream 334 * @param name The name of the stream (e.g. "Used space") 335 * @param minValue The minimum value for any item in this stream. 336 * Values less than this will be represented as "minValue-" 337 * @param maxValue The maximum value for any item in this stream. 338 * Values greater than this will be represented as "maxValue+" 339 * @param zeroValue The zero value for this stream 340 * @param defaultValue The default value for this stream 341 * @param stringPre A string to prefix values (e.g. "Used: ") 342 * @param stringPost A string to suffix values (e.g. " bytes.") 343 * @param presentation How a stream value is to be presented. 344 * @param paintStyle How the value is to be painted. 345 * @param indexMaxStream The index of the maximum stream if the presentation is *_VAR. 346 * @param colour The default colour for tiles of this stream 347 * @param summary Is a summary enabled? 348 * @see IntStream 349 * 350 * @return A concrete VM-specific IntStream instance. 351 */ 352 public static IntStream newGCspyIntStream( 353 AbstractDriver driver, 354 String name, 355 int minValue, 356 int maxValue, 357 int zeroValue, 358 int defaultValue, 359 String stringPre, 360 String stringPost, 361 int presentation, 362 int paintStyle, 363 int indexMaxStream, 364 Color colour, 365 boolean summary) { 366 return factory.newGCspyIntStream(driver, name, minValue, maxValue, 367 zeroValue, defaultValue, stringPre, stringPost, 368 presentation, paintStyle, indexMaxStream, 369 colour, summary); 370 } 371 372 /** 373 * Create a new ShortStream instance using the appropriate 374 * VM-specific concrete ShortStream sub-class. 375 * 376 * @param driver The driver that owns this Stream 377 * @param name The name of the stream (e.g. "Used space") 378 * @param minValue The minimum value for any item in this stream. 379 * Values less than this will be represented as "minValue-" 380 * @param maxValue The maximum value for any item in this stream. 381 * Values greater than this will be represented as "maxValue+" 382 * @param zeroValue The zero value for this stream 383 * @param defaultValue The default value for this stream 384 * @param stringPre A string to prefix values (e.g. "Used: ") 385 * @param stringPost A string to suffix values (e.g. " bytes.") 386 * @param presentation How a stream value is to be presented. 387 * @param paintStyle How the value is to be painted. 388 * @param indexMaxStream The index of the maximum stream if the presentation is *_VAR. 389 * @param colour The default colour for tiles of this stream 390 * @param summary Is a summary enabled? 391 * @see IntStream 392 * 393 * @return A concrete VM-specific IntStream instance. 394 */ 395 public static ShortStream newGCspyShortStream( 396 AbstractDriver driver, 397 String name, 398 short minValue, 399 short maxValue, 400 short zeroValue, 401 short defaultValue, 402 String stringPre, 403 String stringPost, 404 int presentation, 405 int paintStyle, 406 int indexMaxStream, 407 Color colour, 408 boolean summary) { 409 return factory.newGCspyShortStream(driver, name, minValue, maxValue, 410 zeroValue, defaultValue, stringPre, stringPost, 411 presentation, paintStyle, indexMaxStream, 412 colour, summary); 413 } 414}