blob: 56218c6a2889c3122685b740612cd4f98be5e1d0 [file] [log] [blame]
/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Common Public License (CPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/cpl1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.vmutil.options;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.*;
/**
* The abstract base class for all option sets.
*
* Concrete instantiations of this class include logic
*
* All options within the system should have a unique name. No
* two options shall have a name that is the same when a case
* insensitive comparison between the names with spaces removed
* is performed. Only basic alphanumeric characters and spaces
* are allowed.
*
* The VM is required to provide a one way mapping function that
* takes the name and creates a VM style name, such as mapping
* "No Finalizer" to noFinalizer. The VM may not remove any letters
* when performing this mapping but may remove spaces and change
* the case of any character.
*/
public abstract class OptionSet {
private Option head;
private Option tail;
private boolean loggingChanges;
/**
* Initialize the option set so that options can be created.
*/
protected OptionSet() {
head = null;
tail = null;
loggingChanges = false;
}
/**
* Register the option to this set, computing its key in the process.
*
* @param o The option to register.
*/
final String register(Option o, String name) {
if (tail == null) {
tail = head = o;
} else {
tail.setNext(o);
tail = o;
}
return computeKey(name);
}
/**
* Using the VM determined key, look up the corresponding option,
* or return null if an option can not be found.
*
* @param key The (unique) option key.
* @return The option, or null.
*/
public final Option getOption(String key) {
Option o = getFirst();
while (o != null) {
if (o.getKey().equals(key)) {
return o;
}
o = o.getNext();
}
return null;
}
/**
* Return the first option. This can be used with the getNext method to
* iterate through the options.
*
* @return The first option, or null if no options exist.
*/
public final Option getFirst() {
return head;
}
public void logChange(Option o) {
if (loggingChanges) {
logString("Option Update: ");
log(o);
}
}
/**
* Log the option value in plain text.
*
* @param o The option to log.
*/
public void log(Option o) {
logString("Option '");
logString(o.getKey());
logString("' = ");
logValue(o, false);
logNewLine();
}
/**
* Log the option value in Xml.
*
* @param o The option to log.
*/
public void logXml(Option o) {
logString("<option name=\"");
logString(o.getKey());
logString("\" value=\"");
logValue(o, true);
logString("\"/>");
logNewLine();
}
/**
* Log the option values in Xml.
*/
public void logXml() {
logString("<options>");
logNewLine();
for(Option o = getFirst(); o != null; o = o.getNext()) {
logXml(o);
}
logString("</options>");
logNewLine();
}
/**
* Format and log an option value.
*
* @param o The option.
* @param forXml Is this part of xml output?
*/
protected abstract void logValue(Option o, boolean forXml);
/**
* Log a string.
*/
protected abstract void logString(String s);
/**
* Print a new line.
*/
protected abstract void logNewLine();
/**
* Determine the VM specific key for a given option name. Option names are
* space delimited with capitalised words (e.g. "GC Verbosity Level").
*
* @param name The option name.
* @return The VM specific key.
*/
protected abstract String computeKey(String name);
/**
* A non-fatal error occurred during the setting of an option. This method
* calls into the VM and shall not cause the system to stop.
*
* @param o The responsible option.
* @param message The message associated with the warning.
*/
protected abstract void warn(Option o, String message);
/**
* A fatal error occurred during the setting of an option. This method
* calls into the VM and is required to cause the system to stop.
*
* @param o The responsible option.
* @param message The error message associated with the failure.
*/
protected abstract void fail(Option o, String message);
/**
* Convert bytes into pages, rounding up if necessary.
*
* @param bytes The number of bytes.
* @return The corresponding number of pages.
*/
@Uninterruptible
protected abstract int bytesToPages(Extent bytes);
/**
* Convert from pages into bytes.
* @param pages the number of pages.
* @return The corresponding number of bytes.
*/
@Uninterruptible
protected abstract Extent pagesToBytes(int pages);
}