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}