FAQ
***

Questions frequently asked by Ovm users
=======================================

Why does `gen-ovm' die with `Configuration Error...'?
-----------------------------------------------------

   Image building sometimes fails with the error, `Configuration Error:
in CALLING-CLASS: invalid configuration of BASE-TYPE: SELECTED-TYPE is
not a subtype of NEEDED-TYPE.'  This happens when trying to use an
incompatible set build options.  Code in the OVM (CALLING-CLASS in
particular) needs additional features from the implemenation of
BASE-TYPE, but these features are not provided by the configured
implemenation (SELECTED-TYPE).

   Common sources of this error include:
   * Using an RTSJ aware GC without RTSJ threads.  This can be fixed by
     replacing `-model=MostlyCopyingRegions-B_Mf_F_H' with
     `-model=MostlyCopyingWB-B_Mf_F_H' or another non-realtime
     allocator.

   * Using RTSJ threads with a non-RTSJ aware GC.  This can be fixed by
     invoking `gen-ovm' with `-model=MostlyCopyingRegions-B_Mf_F_H' or
     any other realtime allocator.

   * Using a precise GC with a compiler that doesn't support it.  This
     can be fixed by selecting an `-engine' that supports precise GC
     (such as `intepreter' or `j2c', or by selecting a `-model' that
     does not require stack maps (such as `minimalMM-B_Mf', or one of
     the `MostlyCopying' allocators).

   If none of the above apply, your best bet is to grep for BASE-TYPE
in the ovm config files.  (By default, these files are installed at
`/usr/local/ovm/config'.)

Why does `ovm' die with an assertion failure complaining about abstract methods?
--------------------------------------------------------------------------------

   If such an error occurs at runtime, `gen-ovm' printed a warning at
at compile time describing the problem in greater detail.  These errors
typically occur in application bytecode due to bugs in Ovm's method
resolution code (see *Note Bin compat::).

   Ovm developers encounter these errors more frequently.  These errors
occur on a call to a VM-internal method that itself calls a method that
only exists at image-build time (inside the `gen-ovm' process).
Warnings from `gen-ovm' indicate which methods it treats as build time,
and the line number of the method's first build-time call.

Why does `gen-ovm' report that methods clearly inherited from interfaces are not found?
---------------------------------------------------------------------------------------

   J2c's compile-time messages sometimes complain that methods in
`javax.realtime' can't be found, or that application methods can't be
found when said methods are clearly inheritted from interfaces.  Both
these problems can be avoided by invoking `javac' more carefully.
`javac' should always be invoked as follows:
     javac -bootclasspath /usr/local/ovm/classes/ovm_rt_user.jar     \
           -target 1.1                                               \
           JAVA-FILES
   (You may need to change the path to `ovm_rt_user.jar' depending on
where, or whether, you chose to install Ovm.)  No other definitions of
`javax.realtime' should be present in `javac''s `-classpath' or
`-bootclasspath' lists.

   Setting the appropriate `-bootclasspath' ensures that your code is
compiled against the Ovm's `javax.realtime' implemenation, rather than
code that implements another version of the RTSJ, or no version of the
RTSJ at all.

   Setting `-target' ensures that `javac' will generate class files
that Ovm can understand.

Why does `ovm' dies with an assertion failure complaining about a `reflective call to `unreachable' method'?
------------------------------------------------------------------------------------------------------------

   The current version of J2c requires complete knowledge of reflection
at image-build time.  Every method that is invoked reflectively must be
listed in the `-ud-reflective-methods' switch.

   Building up this list can be extremely tedious, so we provide two
alternatives:
   * The build-time option `-reflective-method-trace=`file''    can be
     used with the interpreter or simplejit to dump a list all methods
      invoked reflectively in the named file.  When collecting these
     traces, you should be careful to excersize all code paths that may
       lead to a reflective all.  Once a complete list of reflective
     method    invocations is built, it can be fed back into ovm with
     `gen-ovm -engine=j2c -ud-reflective-methods=@`file''.

     A method will only be listed once on each JVM run, but since the
     OVM    appends to this file, one can accumulate a list of methods
     invoked    across multiple runs.  When collecting traces across
     multiple runs,    it may be a good idea to run `sort -u'.

   * `-app-methods-live' forces j2c to treat all methods defined    by
     the application classloader as possible targets of reflective
     invocation.  Since this option increases build time, bloats the
     boot image, and inhibits optimization, it should be used with
     caution. *NOTE:* `-app-methods-live' has no effect in
     combination with `-opt=run'.

Why doesn't the above work for a method named `CLASS__0003cclinit_0003e_N', and what is this method anyway?
-----------------------------------------------------------------------------------------------------------

   The latter question is the key one: `_0003cclinit_0003e_'
corresponds to a `<clinit>' method in Java bytecode, and this method
contains CLASS's static initializers.(1)  Static initializers are not
explicitly invoked through Java reflection, but may be implicitly
invoked through `Class.forName()'.  See *Note NoClassDef:: for ways to
ensure that a class, and its static initializers are included in an Ovm
image.

   ---------- Footnotes ----------

   (1) Note the sequence of two `c's.  These methods should not be
confused with constructors named `CLASS__0003cinit_0003e_N'.  See *Note
gdb Tutorial:: for a more complete description of j2c's naming
conventions.

Why am I getting `NoClassDefFoundError' for a class that is clearly defined?
----------------------------------------------------------------------------

   Typically, this error occurs when a class C is only referenced
through `Class.forName()' calls or `C.class' expressions, but this
error may also come up if the standard library uses `Class.forName()'
incorrectly.  If `u1_C' does not appear in `structs.hh', gen-ovm must
be explicitly told to include C with the `-ud-reflective-classes'
option.

   As with `-ud-reflective-methods', Ovm provides a couple ways to
build this list automatically.
   * `-app-classes-live' forces the OVM to treat all classes    defined
     by the application classloader as possible targets of
     `forName()' calls.  Since this option increases build time,
     bloats the boot image, and inhibits optimization, it should be used
       with caution.  *NOTE:* `-app-classes-live' has little    effect
     in combination with `-opt=run'.

   * `-reflective-class-trace=`file''    can be used in combination
     with `-app-classes-live' to    collect a list of class names that
     are passed to `forName()' at    runtime.  The complete list can be
     fed back to `gen-ovm' with    `-ud-reflective-classes=@`file''.

     A class will only be listed once on each JVM run, but    since the
     OVM appends to this file, one can accumulate a list of    classes
     invoked across multiple runs.  When collecting traces    across
     multiple runs, it may be a good idea to run `sort -u'.

How can I run `strip' under Darwin?
-----------------------------------

   In some configurations, ovm generates absolute symbols that point
into the initial heap image.  For some reason, MacOS's ld does not
relocate references to these symbols.  `strip -ruA' will strip all
symbols that are not needed at runtime.

How do I enable fine-grained timers under RTLinux?
--------------------------------------------------

   OVM uses a default timer interrupt rate of 10ms. This affects all
timed operations, such as sleeps, waits, RTSJ periodic thread release,
and RTSJ timers. The timer interrupt rate can be set at runtime using
the `-period' runtime argument:
     ./ovm -period=NNN <MAIN CLASS NAME> <ARGS>
   where NNN is a value in microseconds. The requested value will be
rounded up to a multiple of the supported underlying timer resolution. A
warning is printed if you ask for a timer interrupt rate that is shorter
than the supported timer resolution, but no warning is printed if the
rate needs to be rounded up.  OVM reports the actual timer interrupt
rate being used at start-up time.

   On the majority of Linux systems the supported timer resolution is
10ms. This cannot be changed. Apparently in 2.6 kernel Linux systems
this will reduce to 1ms. When running on the licensed Timesys Linux RT
system a high resolution implementation of the POSIX real-time timers is
available, with a resolution of 1us. To use these timers you must ensure
that the Timesys library, `librk-rt.a', is available by setting the
`LIBRARY_PATH' environment variable when running configure, and when
building the OVM and an OVM image.

OK, how do I link with RTLinux's magic library?
-----------------------------------------------

   First you must have the licensed version of Timesys Linux RT, not the
GPL version. If you can find `librk-rt.a' then you have the licensed
version.

   Second, `librk-rt.a' must be locatable by `ld' when the `configure'
script runs and when building the OVM and any image. To do this either
`librk-rt.a' must be in the default location looked in by `ld' (which
is `/usr/lib' normally) or you must set the `LIBRARY_PATH' environment
variable to point to the directory where `lbrk-rt.a' is located. Check
the `config.log' file to see if `ld' was able to find the library when
`configure' ran. Check the build output to see if `-lrk-rt' is being
passed as a link option.

   You might be tempted to edit `ld.so.conf' instead of setting
`LIBRARY_PATH'.  This is a bad idea.  `ld.so.conf' tells `ld.so' where
to find dynamically loaded libraries at runtime.  You need to tell `ld'
where to find the statically linked `librk-rt.a' library at link time -
the only way to do this (apart from recompiling `ld') is to set the
`LIBRARY_PATH' environment variables (*NOTE*: this is not
`LD_LIBRARY_PATH' which is again telling `ld.so' how to dynamically
load libraries at runtime.)

Questions frequently asked by Ovm developers
============================================

How can I use Eclipse on Ovm source code?
-----------------------------------------

   Go to `src/' within your build directory, and run `make
eclipse-dotfiles'.  This target will overwrite `.classpath' and
`.project' in your toplevel source directory, and allow you to run
Eclipse as before.  The `make' target is more reliable than the
`.classpath' and `.project' files in CVS, because it knows whether a
seperate build directory is being used, and it knows whether
`sun.tools.javac.Main' is available in `rt.jar'.

How can I use JDE on Ovm source code?
-------------------------------------

   Hiroshi has been using JDE for quite some time without complaints,
while Jason only recently started and has several complains
   * Some features, such as JDEBug and the crossreference tool don't
     work with XEmacs.  JDEBug can be (at least partially) fixed (*Note
     JDE init.el::), while the crossreference and class parsing stuff
     may contain deeper bugs.

   * It doesn't feel like an emacs mode.  Debugging commands have
     unconventional names and bindings, completion is unlike anything
     found Unix software such as emacs, bash, or tcsh, and the whole
     compile/build thing is funny.  In particular, the command
     `jde-build' really shouldn't exist.  Instead, `M-x compile' should
     have a seperate history and default command for JDE buffers.

   * The javac-server thing would seem to work best with javamake.
     `C-c C-v C-c' would trigger javamake dependency checking, and
     behave much like Eclipse after files are saved.  However, it is
     entirely non-obvious whether javamake can be used here.

   * The debugger seems to be starved for features.  I can't figure out
     how to break on exception throw, or how to see the `toString'
     representation of a java object.


   I was able to get many JDE-mode features working with Ovm and xemacs
by adding the following snippets to config files

Changes to `~/xemacs/init.el' for JDE
.....................................

     (when (featurep 'xemacs)
       ;; GNU Emacs compatibility
       (defun line-beginning-position (&optional n)
         (save-excursion
           (if (and n (not (= n 1)))
     	  (forward-line (- n 1)))
           (beginning-of-line)
           (point)))
     
       (defun line-end-position (&optional n)
         (save-excursion
           (if (and n (not (= n 1)))
     	  (forward-line (- n 1)))
           (end-of-line)
           (point)))
     
       (defun replace-regexp-in-string (regexp rep string
     				   &optional fixedcase literal subexp start)
         "Replace all occurrences of REGEXP in STRING with REP.
     The FIXEDCASE, and LITERAL parameters are passed to replace-match and
     START is the initial offset passed to string-match.  The optional SUBEXP
     parameter is not supported.
     
     See replace-regexp-in-string as defined by GNU Emacs."
         (assert (not subexp))
         (while (string-match regexp string start)
           (let ((tail (- (length string) (match-end 0)))
     	    (repstr (if (functionp rep)
     			(funcall rep (substring string
     						(match-beginning 0)
     						(match-end 0)))
     		      rep)))
     	(setq string (replace-match repstr fixedcase literal string))
     	(setq start (- (length string) tail))))
         string)
     
       ;; jde-parse-class-get-next-constant does not work under xemacs because
       ;; it assumes (eq ?\n 10) is true, rather than (= ?\n 10).
       ;; As a result, the crossreference stuff doesn't work.
       )
     
     (push '("\\.java\\'" . jde-mode) auto-mode-alist)
     
     (defun jde-setup ()
         (local-set-key "\M-\C-i"  #'jde-complete-in-line)
         (local-set-key "\M-."     #'jde-open-class-at-point)
         ;; not sure how to rebind \C-h without rebinding backspace
         (local-set-key "\C-hd"    #'jde-help-symbol)
         (if (featurep 'xemacs)
     	(local-set-key [(backspace)] #'backward-delete-char))
         (local-set-key "\C-c\C-m" #'jde-import-find-and-import)
         (local-set-key "\C-c\C-t" #'jde-open-class-source)
         )
     
     (add-hook 'jde-mode-hook #'jde-setup)

A prj.el target for `OpenVM/src/Makefile.mk'
............................................

     prj.el: Makefile.mk
     	(echo '(setq jde-project-name "OpenVM")';			     \
     	 echo '(setq jde-global-classpath';				     \
     	 echo '      (list "$(shell pwd)"';				     \
     	 echo '             "$(subst :," ",$(JAVA_CLASSPATH))"))';	     \
     	 echo "(setq jde-compile-option-directory \"`pwd`\")";		     \
     	 echo "(setq jde-sourcepath '(\"$(srcdir)\" \"`pwd`\"))";	     \
     	 echo '(setq jdb-compile-option-target "1.1")';			     \
     	 echo "(setq jde-build-function '(jde-make))";			     \
     	 echo '(setq jde-make-args "-w -C $(shell pwd)")';		     \
     	 echo '(setq jde-run-application-class';			     \
     	 echo '      "s3.services.bootimage.Driver")';			     \
     	 echo '(setq jde-run-option-properties';			     \
     	 echo "      '((\"ovm.stitcher.path\" .";			     \
     	 echo '         "$(top_srcdir)/config:$(shell cd ../config; pwd)")'; \
     	 echo '        ("ovm.stitcher.file" . "stitchery")))';		     \
     	 echo "(setq jde-run-option-vm-args '(\"-Xmx700m\"))";		     \
     	 echo "(setq jde-db-option-properties jde-run-option-properties";    \
     	 echo "	     jde-db-option-vm-args  jde-run-option-vm-args)";	     \
     	 echo "(setq jde-run-read-app-args t)";				     \
     	 echo "(setq jde-help-docsets";					     \
     	 echo "      (cons '(\"User (javadoc)\"";			     \
     	 echo '              "http://ovmj.org/doc/javadoc"';		     \
     	 echo '              nil)';					     \
     	 echo '      jde-help-docsets))';				     \
     	 echo '(setq jde-xref-store-prefixes (list "ovm" "s3"))';	     \
     	 echo '(setq jde-xref-db-base-directory "$(shell pwd)/jde-xref")'    \
     	 echo '(setq c-basic-offset 4)';				     \
     	 ) > $(srcdir)/prj.el

How can I run tests manually?
-----------------------------

   By running `make' in the test directory, of course.
   * `make' will compile and run the standard tests in the default
     configuration

   * `make ENGINE=E MODEL=M THREADS=T' will compile and run the
     configuration defined by E, M, and T.

   * `make regression-test' will run through the entire test suite
     (which currently includes 19 configurartions).

How are tests run automatically?
--------------------------------

   They are run on `aardvark.cs.purdue.edu' as the `ovm' psuedo-user.
If all tests pass, I delete the entire OpenVM tree.  Otherwise, I
delete the VM-gen directories of all passing configurations.  (These
img files really eat up space.)  If you are Fil and you are lucky (an
unlikely combination), some impossible-to-reproduce bug has resulting
in a j2c core dump during automated testing.  You can now:
     me@here> ssh aardvark
     me@aardvark> sudo -u ovm bash
     password: YOUR OWN PASSWORD
     ovm@aardvark> cd /scrach/ovm/OpenVM-YYYYMMDDHH00/test/build-FAILED-TEST
     ovm@aardvark> gdb ovm core.NNNN

How are benchmarks run automatically?
-------------------------------------

   Benchmarks are run on `cordelia' by `RTJUnit'.  To get a better idea
of what's going on, check out a copy of `RTJUnit' from `/p/sss/cvs',
and take a look at `RTJUnit/scripts/'.  RTJUnit's cron jobs updated
themselves from CVS, so any changes that are committed to the cvs tree
will become part of the benchmark run within a day or two.

How is the anonymous CVS repository updated?
--------------------------------------------

   The anonymous CVS repository available at `ovmj.org' is a mirror of
the live repository at `/p/sss/cvs'.  The mirror is updated nightly in
a cron job run by `ovm@aardvark'.

How is the documentation on `ovmj.org' updated?
-----------------------------------------------

   Manually, through the makefiles.  On a Purdue machine:
     make weball && sudo -u ovm make webinstall
   will update the javadoc, the manual, and this FAQ.

   If you want to update other parts of <http://www.ovmj.org>, you can
commit changes to the `OpenVMDoc' cvs repository, and wait for a cron
job to propagate the changes to `ovmj.org'

