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.jikesrvm.runtime;
014
015import org.jikesrvm.VM;
016import org.jikesrvm.jni.FunctionTable;
017import org.jikesrvm.mm.mminterface.MemoryManager;
018import org.vmmagic.pragma.Entrypoint;
019import org.vmmagic.pragma.Uninterruptible;
020import org.vmmagic.pragma.Untraced;
021import org.vmmagic.unboxed.Address;
022import org.vmmagic.unboxed.AddressArray;
023import org.vmmagic.unboxed.Extent;
024import org.vmmagic.unboxed.Offset;
025
026/**
027 * Information required to start the virtual machine and communicate
028 * with the outside world.
029 *
030 * <p> The virtual machine image consists entirely of java objects.
031 * The first java-object, the boot record, is the communication area between
032 * the host operating system and the virtual machine. It consists of read-only
033 * fields containing startup information used by the assembler bootstrap
034 * loader, by the virtual machine's initializer methods, and by the virtual
035 * machine's operating system call interface methods.
036 *
037 * <p> See also: BootImageWriter.main(), jvm.c
038 *
039 * <p>The boot record looks like this
040 * (note that fields are layed out "backwards"):
041 *
042 * <pre>
043 *                       lo-mem
044 *                  +---------------+
045 *                  |   fieldN-1    |
046 *                  +---------------+
047 *                  |     ...       |
048 *                  +---------------+
049 *                  |    field1     |
050 *                  +---------------+
051 *                  |    field0     |
052 *                  +---------------+ \
053 *                  |  tib pointer  |  |
054 *                  +---------------+  | object header
055 *                  |  lock word    |  |
056 *                  +---------------+ /
057 *                       hi-mem
058 * </pre>
059 *
060 * The "spRegister" field of the boot record points to the word immediately
061 * preceeding the top of a stack object (ie. it's ready to accept a "push"
062 * instruction). The stack object is an array of words that looks like this:
063 *
064 * <pre>
065 *                       lo-mem
066 *                  +---------------+ \
067 *                  |  tib pointer  |  |
068 *                  +---------------+  | array
069 *                  |  lock word    |  |   object
070 *                  +---------------+  |      header
071 *                  |    .length    |  |
072 *                  +---------------+ /
073 *                  |    &lt;empty&gt;    |
074 *                  +---------------+
075 *                  |     ...       |
076 *                  +---------------+
077 *                  |    &lt;empty&gt;    |
078 *                  +---------------+
079 *    spRegister -&gt;      hi-mem
080 * </pre>
081 *
082 * <P> The "ipRegister" field of the boot record points to the first word
083 * of an array of machine instructions comprising
084 * the virtual machine's startoff code -- see "VM.boot()".
085 *
086 * <P> The "tocRegister" field of the boot record points to an array of words
087 * containing the static fields and method addresses of the virtual
088 * machine image -- see "Statics.slots[]".
089 *
090 * <P> The remaining fields of the boot record serve as a function linkage area
091 * between services residing in the host operating system and services
092 * residing in the virtual machine.
093 */
094public class BootRecord {
095  /**
096   * The following static field is initialized by the boot image writer.
097   * It allows the virtual machine to address the boot record using normal
098   * field access instructions (the assembler bootstrap function, on the other
099   * hand, simply addresses the boot record as the first object in
100   * the boot image).
101   */
102  @Entrypoint
103  public static BootRecord the_boot_record;
104
105  public BootRecord() {
106    int len = 2 * (1 + MemoryManager.getMaxHeaps());
107    heapRanges = AddressArray.create(len);
108    // Indicate end of array with sentinel value
109    heapRanges.set(len - 1, Address.fromIntSignExtend(-1));
110    heapRanges.set(len - 2, Address.fromIntSignExtend(-1));
111  }
112
113  public void showHeapRanges() {
114    for (int i = 0; i < heapRanges.length() / 2; i++) {
115      VM.sysWrite(i, "  ");
116      VM.sysWrite(heapRanges.get(2 * i));
117      VM.sysWrite("  ", heapRanges.get(2 * i + 1));
118      VM.sysWrite("  ");
119    }
120  }
121
122  @Uninterruptible
123  public void setHeapRange(int id, Address start, Address end) {
124    if (VM.VerifyAssertions) VM._assert(id < heapRanges.length() - 2);
125    heapRanges.set(2 * id, start);
126    heapRanges.set(2 * id + 1, end);
127  }
128
129  // The following fields are written when the virtual machine image
130  // is generated (see BootImage.java), loaded (see jvm.C),
131  // or executed (see VM.java).
132  //
133  // If you add/remove/change fields here, be sure to change the
134  // corresponding code in jvm.c
135
136  /**
137   * address at which image is to be loaded into memory
138   */
139  public Address bootImageDataStart;
140  public Address bootImageDataEnd;
141  public Address bootImageCodeStart;
142  public Address bootImageCodeEnd;
143  public Address bootImageRMapStart;
144  public Address bootImageRMapEnd;
145
146  /**
147   * initial size of heap
148   */
149  public Extent initialHeapSize;
150
151  /**
152   * maximum size of heap
153   */
154  public Extent maximumHeapSize;
155
156  /** size of a virtual memory page in bytes */
157  public Extent bytesInPage;
158
159  @Untraced // because bootloader code must be able to access it
160  public AddressArray heapRanges; // [start1, end1, ..., start_k, end_k, -1, -1]
161  // C-style termination with sentinel values
162  /**
163   * Verbosity level for booting
164   * set by -X:verboseBoot=
165   */
166  public int verboseBoot = 0;
167
168  /**
169   * Print messages when delivering hardware exceptions to threads?
170   * Set by -X:verboseSignalHandling
171   */
172  public int verboseSignalHandling = 0;
173
174  // RVM startoff
175  //
176  public Address spRegister;   // value to place into SP register
177  public Address ipRegister;   // value to place into IP register
178  public Address tocRegister;  // value to place into JTOC register
179
180  /**
181   * flag to indicate RVM has completed booting and ready to run Java programs
182   * added by Ton Ngo for JNI support
183   */
184  int bootCompleted;       // use for start up by JNI_CreateJavaVM
185
186  /**
187   * address of JavaVM, used by JNI_OnLoad and JNIEnv.GetJavaVM,
188   * defined in jvm.c
189   */
190  public Address sysJavaVM;
191
192  /**
193   * Reference to JNI function table
194   */
195  @Untraced // because bootloader code must be able to access it
196  public FunctionTable JNIFunctions;
197
198  // Additional RVM entrypoints
199  //
200  /**
201   * method id for inserting stackframes at site of hardware traps
202   */
203  int hardwareTrapMethodId;
204  /**
205   * jtoc offset of RuntimeEntrypoints.deliverHardwareException()
206   */
207  Offset deliverHardwareExceptionOffset;
208  /**
209   * jtoc offset of RVMThread.dumpStackAndDie(I)
210   */
211  public Offset dumpStackAndDieOffset;
212  /**
213   * jtoc offset of RVMThread.bootThread
214   */
215  public Offset bootThreadOffset;
216  /**
217   * jtoc offset of RVMThread.debugRequested
218   */
219  Offset debugRequestedOffset;
220  /**
221   * an external signal has been sent e.g. kill -signalnumber processid
222   */
223  @Entrypoint
224  int externalSignalFlag;
225
226  // Host operating system entrypoints - see "sys.cpp"
227  //
228
229  // lowlevel write to console
230  public Address sysConsoleWriteCharIP;
231  public Address sysConsoleWriteIntegerIP;
232  public Address sysConsoleWriteLongIP;
233  public Address sysConsoleWriteDoubleIP;
234
235  // startup/shutdown
236  public Address sysExitIP;
237  public Address sysArgIP;
238
239  // misc. info on the process -- used in startup/shutdown
240  public Address sysGetenvIP;
241
242  // memory
243  public Address sysCopyIP;
244  public Address sysMemmoveIP;
245  public Address sysMallocIP;
246  public Address sysCallocIP;
247  public Address sysFreeIP;
248  public Address sysZeroNTIP;
249  public Address sysZeroIP;
250  public Address sysZeroPagesIP;
251  public Address sysSyncCacheIP;
252
253  // files
254  public Address sysReadByteIP;
255  public Address sysWriteByteIP;
256  public Address sysReadBytesIP;
257  public Address sysWriteBytesIP;
258
259  // mmap - memory mapping
260  public Address sysMMapIP;
261  public Address sysMMapErrnoIP;
262  public Address sysMProtectIP;
263
264  // threads
265  public Address sysNumProcessorsIP;
266  public Address sysThreadBindSupportedIP;
267  public Address sysThreadBindIP;
268  public Address sysThreadCreateIP;
269  public Address sysThreadYieldIP;
270  public Address sysGetThreadIdIP;
271  public Address sysStashVMThreadIP;
272  public Address sysThreadTerminateIP;
273  public Address sysGetThreadPriorityHandleIP;
274  public Address sysGetThreadPriorityIP;
275  public Address sysSetThreadPriorityIP;
276
277  // monitors
278  public Address sysMonitorCreateIP;
279  public Address sysMonitorDestroyIP;
280  public Address sysMonitorEnterIP;
281  public Address sysMonitorExitIP;
282  public Address sysMonitorTimedWaitAbsoluteIP;
283  public Address sysMonitorWaitIP;
284  public Address sysMonitorBroadcastIP;
285
286  // arithmetic
287  @Entrypoint
288  public Address sysLongDivideIP;
289  @Entrypoint
290  public Address sysLongRemainderIP;
291  @Entrypoint
292  public Address sysLongToFloatIP;
293  @Entrypoint
294  public Address sysLongToDoubleIP;
295  @Entrypoint
296  public Address sysFloatToIntIP;
297  @Entrypoint
298  public Address sysDoubleToIntIP;
299  @Entrypoint
300  public Address sysFloatToLongIP;
301  @Entrypoint
302  public Address sysDoubleToLongIP;
303  @Entrypoint
304  public Address sysDoubleRemainderIP;
305  public Address sysPrimitiveParseFloatIP;
306  public Address sysPrimitiveParseIntIP;
307  public Address sysParseMemorySizeIP;
308
309  // time
310  Address sysCurrentTimeMillisIP;
311  Address sysNanoTimeIP;
312  Address sysNanoSleepIP;
313
314  // shared libraries
315  Address sysDlopenIP;
316  Address sysDlsymIP;
317
318  // var args
319  public Address sysVaCopyIP;
320  public Address sysVaEndIP;
321  public Address sysVaArgJbooleanIP;
322  public Address sysVaArgJbyteIP;
323  public Address sysVaArgJcharIP;
324  public Address sysVaArgJshortIP;
325  public Address sysVaArgJintIP;
326  public Address sysVaArgJlongIP;
327  public Address sysVaArgJfloatIP;
328  public Address sysVaArgJdoubleIP;
329  public Address sysVaArgJobjectIP;
330
331  // VMMath
332  public Address sysVMMathSinIP;
333  public Address sysVMMathCosIP;
334  public Address sysVMMathTanIP;
335  public Address sysVMMathAsinIP;
336  public Address sysVMMathAcosIP;
337  public Address sysVMMathAtanIP;
338  public Address sysVMMathAtan2IP;
339  public Address sysVMMathCoshIP;
340  public Address sysVMMathSinhIP;
341  public Address sysVMMathTanhIP;
342  public Address sysVMMathExpIP;
343  public Address sysVMMathLogIP;
344  public Address sysVMMathSqrtIP;
345  public Address sysVMMathPowIP;
346  public Address sysVMMathIEEEremainderIP;
347  public Address sysVMMathCeilIP;
348  public Address sysVMMathFloorIP;
349  public Address sysVMMathRintIP;
350  public Address sysVMMathCbrtIP;
351  public Address sysVMMathExpm1IP;
352  public Address sysVMMathHypotIP;
353  public Address sysVMMathLog10IP;
354  public Address sysVMMathLog1pIP;
355
356  // system calls for alignment checking
357  public Address sysEnableAlignmentCheckingIP;
358  public Address sysDisableAlignmentCheckingIP;
359  public Address sysReportAlignmentCheckingIP;
360
361  /* FIXME: We *really* don't want all these syscalls here unconditionally --- need to push them out somehow */
362  // GCspy entry points
363  public Address gcspyDriverAddStreamIP;
364  public Address gcspyDriverEndOutputIP;
365  public Address gcspyDriverInitIP;
366  public Address gcspyDriverInitOutputIP;
367  public Address gcspyDriverResizeIP;
368  public Address gcspyDriverSetTileNameRangeIP;
369  public Address gcspyDriverSetTileNameIP;
370  public Address gcspyDriverSpaceInfoIP;
371  public Address gcspyDriverStartCommIP;
372  public Address gcspyDriverStreamIP;
373  public Address gcspyDriverStreamByteValueIP;
374  public Address gcspyDriverStreamShortValueIP;
375  public Address gcspyDriverStreamIntValueIP;
376  public Address gcspyDriverSummaryIP;
377  public Address gcspyDriverSummaryValueIP;
378
379  public Address gcspyIntWriteControlIP;
380
381  public Address gcspyMainServerAddDriverIP;
382  public Address gcspyMainServerAddEventIP;
383  public Address gcspyMainServerInitIP;
384  public Address gcspyMainServerIsConnectedIP;
385  public Address gcspyMainServerOuterLoopIP;
386  public Address gcspyMainServerSafepointIP;
387  public Address gcspyMainServerSetGeneralInfoIP;
388  public Address gcspyMainServerStartCompensationTimerIP;
389  public Address gcspyMainServerStopCompensationTimerIP;
390
391  public Address gcspyStartserverIP;
392
393  public Address gcspyStreamInitIP;
394
395  public Address gcspyFormatSizeIP;
396  public Address gcspySprintfIP;
397
398  // perf event support
399  public Address sysPerfEventInitIP;
400  public Address sysPerfEventCreateIP;
401  public Address sysPerfEventEnableIP;
402  public Address sysPerfEventDisableIP;
403  public Address sysPerfEventReadIP;
404
405}