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     */
013    package org.mmtk.vm;
014    
015    import org.mmtk.utility.options.Options;
016    import org.mmtk.utility.gcspy.Color;
017    import org.mmtk.utility.gcspy.drivers.AbstractDriver;
018    import org.mmtk.vm.gcspy.ByteStream;
019    import org.mmtk.vm.gcspy.IntStream;
020    import org.mmtk.vm.gcspy.ServerInterpreter;
021    import org.mmtk.vm.gcspy.ServerSpace;
022    import org.mmtk.vm.gcspy.ShortStream;
023    import org.mmtk.vm.gcspy.Util;
024    import org.vmmagic.pragma.Untraced;
025    import org.vmmagic.unboxed.Address;
026    import 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     */
051    public 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      /*
086       * VM-specific functionality captured in a series of singleton classs
087       */
088      @Untraced
089      public static final ActivePlan activePlan;
090      @Untraced
091      public static final Assert assertions;
092      @Untraced
093      public static final Barriers barriers;
094      @Untraced
095      public static final Collection collection;
096      @Untraced
097      public static final Config config;
098      @Untraced
099      public static final Memory memory;
100      @Untraced
101      public static final ObjectModel objectModel;
102      @Untraced
103      public static final ReferenceProcessor weakReferences;
104      @Untraced
105      public static final ReferenceProcessor softReferences;
106      @Untraced
107      public static final ReferenceProcessor phantomReferences;
108      @Untraced
109      public static final FinalizableProcessor finalizableProcessor;
110      @Untraced
111      public static final Scanning scanning;
112      @Untraced
113      public static final Statistics statistics;
114      @Untraced
115      public static final Strings strings;
116      @Untraced
117      public static final TraceInterface traceInterface;
118      @Untraced
119      public static final MMTk_Events events;
120      @Untraced
121      public static final Debug debugging;
122    
123      /*
124       * The remainder is does the static initialization of the
125       * above, reflectively binding to the appropriate host jvm
126       * classes.
127       */
128      private static final Factory factory;
129      private static final String vmFactory;
130    
131      /**
132       * This class initializer establishes a VM-specific factory class
133       * using reflection, and then uses that to create VM-specific concrete
134       * instances of all of the vm classes, initializing the singltons in
135       * this class.  Finally the constants declared in this class are
136       * initialized using the VM-specific singletons.
137       */
138      static {
139        /* Identify the VM-specific factory using reflection */
140        vmFactory = System.getProperty("mmtk.hostjvm");
141        Factory xfa = null;
142        try {
143          xfa = (Factory) Class.forName(vmFactory).newInstance();
144        } catch (Exception e) {
145          e.printStackTrace();
146          System.exit(-1);     // we must *not* go on if the above has failed
147        }
148        factory = xfa;
149    
150        /* Now instantiate the singletons using the factory */
151        activePlan = factory.newActivePlan();
152        assertions = factory.newAssert();
153        barriers = factory.newBarriers();
154        collection = factory.newCollection();
155        memory = factory.newMemory();
156        objectModel = factory.newObjectModel();
157        Options.set = factory.getOptionSet();
158        weakReferences = factory.newReferenceProcessor(ReferenceProcessor.Semantics.WEAK);
159        softReferences = factory.newReferenceProcessor(ReferenceProcessor.Semantics.SOFT);
160        phantomReferences = factory.newReferenceProcessor(ReferenceProcessor.Semantics.PHANTOM);
161        finalizableProcessor = factory.newFinalizableProcessor();
162        scanning = factory.newScanning();
163        statistics = factory.newStatistics();
164        strings = factory.newStrings();
165        traceInterface = factory.newTraceInterface();
166        events = factory.newEvents();
167        debugging = factory.newDebug();
168        config = new Config(factory.newBuildTimeConfig());
169    
170        /* Now initialize the constants using the vm-specific singletons */
171        VERIFY_ASSERTIONS = Assert.verifyAssertionsTrapdoor(assertions);
172        HEAP_START = Memory.heapStartTrapdoor(memory);
173        HEAP_END = Memory.heapEndTrapdoor(memory);
174        AVAILABLE_START = Memory.availableStartTrapdoor(memory);
175        AVAILABLE_END = Memory.availableEndTrapdoor(memory);
176        LOG_BYTES_IN_ADDRESS = Memory.logBytesInAddressTrapdoor(memory);
177        LOG_BYTES_IN_WORD = Memory.logBytesInWordTrapdoor(memory);
178        LOG_BYTES_IN_PAGE = Memory.logBytesInPageTrapdoor(memory);
179        LOG_MIN_ALIGNMENT = Memory.logMinAlignmentTrapdoor(memory);
180        MAX_ALIGNMENT_SHIFT = Memory.maxAlignmentShiftTrapdoor(memory);
181        MAX_BYTES_PADDING = Memory.maxBytesPaddingTrapdoor(memory);
182        ALIGNMENT_VALUE = Memory.alignmentValueTrapdoor(memory);
183        ARRAY_BASE_OFFSET = ObjectModel.arrayBaseOffsetTrapdoor(objectModel);
184        DEBUG = Debug.isEnabledTrapdoor(debugging);
185      }
186    
187      /**
188       * Create a new Lock instance using the appropriate VM-specific
189       * concrete Lock sub-class.
190       *
191       * @see Lock
192       *
193       * @param name The string to be associated with this lock instance
194       * @return A concrete VM-specific Lock instance.
195       */
196      public static Lock newLock(String name) {
197        return factory.newLock(name);
198      }
199    
200      /**
201       * Create a new HeavyCondLock instance using the appropriate VM-specific
202       * concrete Lock sub-class.
203       *
204       * @see Monitor
205       *
206       * @param name The string to be associated with this instance
207       * @return A concrete VM-specific HeavyCondLock instance.
208       */
209      public static Monitor newHeavyCondLock(String name) {
210        return factory.newMonitor(name);
211      }
212    
213      /**
214       * Create a new SynchronizedCounter instance using the appropriate
215       * VM-specific concrete SynchronizedCounter sub-class.
216       *
217       * @see SynchronizedCounter
218       *
219       * @return A concrete VM-specific SynchronizedCounter instance.
220       */
221      public static SynchronizedCounter newSynchronizedCounter() {
222        return factory.newSynchronizedCounter();
223      }
224    
225      /**********************************************************************
226       * GCspy methods
227       */
228    
229      /**
230       * Create a new Util instance using the appropriate
231       * VM-specific concrete Util sub-class.
232       *
233       * @see Util
234       *
235       * @return A concrete VM-specific Util instance.
236       */
237      public static Util newGCspyUtil() {
238        return factory.newGCspyUtil();
239      }
240    
241      /**
242       * Create a new ServerInterpreter instance using the appropriate
243       * VM-specific concrete ServerInterpreter sub-class.
244       *
245       * @see ServerInterpreter
246       *
247       * @return A concrete VM-specific ServerInterpreter instance.
248       */
249      public static ServerInterpreter newGCspyServerInterpreter() {
250        return factory.newGCspyServerInterpreter();
251      }
252    
253      /**
254       * Create a new ServerInterpreter instance using the appropriate
255       * VM-specific concrete ServerInterpreter sub-class.
256       *
257       * @see ServerInterpreter
258       *
259       * @return A concrete VM-specific ServerInterpreter instance.
260       */
261      public static ServerSpace newGCspyServerSpace(
262          ServerInterpreter serverInterpreter,
263          String serverName,
264          String driverName,
265          String title,
266          String blockInfo,
267          int tileNum,
268          String unused,
269          boolean mainSpace) {
270        return factory.newGCspyServerSpace(serverInterpreter, serverName, driverName,
271                                           title, blockInfo, tileNum, unused,
272                                           mainSpace);
273      }
274    
275      /**
276       * Create a new ByteStream instance using the appropriate
277       * VM-specific concrete ByteStream sub-class.
278       *
279       * @param driver        The driver that owns this Stream
280       * @param name           The name of the stream (e.g. "Used space")
281       * @param minValue       The minimum value for any item in this stream.
282       *                       Values less than this will be represented as "minValue-"
283       * @param maxValue       The maximum value for any item in this stream.
284       *                       Values greater than this will be represented as "maxValue+"
285       * @param zeroValue      The zero value for this stream
286       * @param defaultValue   The default value for this stream
287       * @param stringPre      A string to prefix values (e.g. "Used: ")
288       * @param stringPost     A string to suffix values (e.g. " bytes.")
289       * @param presentation   How a stream value is to be presented.
290       * @param paintStyle     How the value is to be painted.
291       * @param indexMaxStream The index of the maximum stream if the presentation is *_VAR.
292       * @param colour         The default colour for tiles of this stream
293       * @see IntStream
294       *
295       * @return A concrete VM-specific ByteStream instance.
296       */
297      public static ByteStream newGCspyByteStream(
298          AbstractDriver driver,
299          String name,
300          byte minValue,
301          byte maxValue,
302          byte zeroValue,
303          byte defaultValue,
304          String stringPre,
305          String stringPost,
306          int presentation,
307          int paintStyle,
308          int indexMaxStream,
309          Color colour,
310          boolean summary) {
311        return factory.newGCspyByteStream(driver, name, minValue,  maxValue,
312                                         zeroValue, defaultValue, stringPre, stringPost,
313                                         presentation, paintStyle, indexMaxStream,
314                                         colour, summary);
315      }
316    
317      /**
318       * Create a new IntStream instance using the appropriate
319       * VM-specific concrete IntStream sub-class.
320       *
321       * @param driver        The driver that owns this Stream
322       * @param name           The name of the stream (e.g. "Used space")
323       * @param minValue       The minimum value for any item in this stream.
324       *                       Values less than this will be represented as "minValue-"
325       * @param maxValue       The maximum value for any item in this stream.
326       *                       Values greater than this will be represented as "maxValue+"
327       * @param zeroValue      The zero value for this stream
328       * @param defaultValue   The default value for this stream
329       * @param stringPre      A string to prefix values (e.g. "Used: ")
330       * @param stringPost     A string to suffix values (e.g. " bytes.")
331       * @param presentation   How a stream value is to be presented.
332       * @param paintStyle     How the value is to be painted.
333       * @param indexMaxStream The index of the maximum stream if the presentation is *_VAR.
334       * @param colour         The default colour for tiles of this stream
335       * @see IntStream
336       *
337       * @return A concrete VM-specific IntStream instance.
338       */
339      public static IntStream newGCspyIntStream(
340          AbstractDriver driver,
341          String name,
342          int minValue,
343          int maxValue,
344          int zeroValue,
345          int defaultValue,
346          String stringPre,
347          String stringPost,
348          int presentation,
349          int paintStyle,
350          int indexMaxStream,
351          Color colour,
352          boolean summary) {
353        return factory.newGCspyIntStream(driver, name, minValue,  maxValue,
354                                         zeroValue, defaultValue, stringPre, stringPost,
355                                         presentation, paintStyle, indexMaxStream,
356                                         colour, summary);
357      }
358    
359      /**
360       * Create a new ShortStream instance using the appropriate
361       * VM-specific concrete ShortStream sub-class.
362       *
363       * @param driver        The driver that owns this Stream
364       * @param name           The name of the stream (e.g. "Used space")
365       * @param minValue       The minimum value for any item in this stream.
366       *                       Values less than this will be represented as "minValue-"
367       * @param maxValue       The maximum value for any item in this stream.
368       *                       Values greater than this will be represented as "maxValue+"
369       * @param zeroValue      The zero value for this stream
370       * @param defaultValue   The default value for this stream
371       * @param stringPre      A string to prefix values (e.g. "Used: ")
372       * @param stringPost     A string to suffix values (e.g. " bytes.")
373       * @param presentation   How a stream value is to be presented.
374       * @param paintStyle     How the value is to be painted.
375       * @param indexMaxStream The index of the maximum stream if the presentation is *_VAR.
376       * @param colour         The default colour for tiles of this stream
377       * @see IntStream
378       *
379       * @return A concrete VM-specific IntStream instance.
380       */
381      public static ShortStream newGCspyShortStream(
382          AbstractDriver driver,
383          String name,
384          short minValue,
385          short maxValue,
386          short zeroValue,
387          short defaultValue,
388          String stringPre,
389          String stringPost,
390          int presentation,
391          int paintStyle,
392          int indexMaxStream,
393          Color colour,
394          boolean summary) {
395        return factory.newGCspyShortStream(driver, name, minValue,  maxValue,
396                                         zeroValue, defaultValue, stringPre, stringPost,
397                                         presentation, paintStyle, indexMaxStream,
398                                         colour, summary);
399      }
400    }