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.options; 014 015import static org.jikesrvm.runtime.ExitStatus.EXIT_STATUS_PRINTED_HELP_MESSAGE; 016 017import org.jikesrvm.VM; 018import org.jikesrvm.runtime.CommandLineArgs; 019import org.jikesrvm.runtime.Memory; 020import org.vmmagic.pragma.Uninterruptible; 021import org.vmmagic.unboxed.Extent; 022import org.vmmagic.unboxed.Word; 023import org.vmutil.options.AddressOption; 024import org.vmutil.options.BooleanOption; 025import org.vmutil.options.EnumOption; 026import org.vmutil.options.FloatOption; 027import org.vmutil.options.IntOption; 028import org.vmutil.options.MicrosecondsOption; 029import org.vmutil.options.Option; 030import org.vmutil.options.PagesOption; 031import org.vmutil.options.StringOption; 032 033/** 034 * Class to handle command-line arguments and options for GC. 035 */ 036public final class OptionSet extends org.vmutil.options.OptionSet { 037 038 private final String prefix; 039 040 public static final OptionSet gc = new OptionSet("-X:gc"); 041 042 private OptionSet(String prefix) { 043 this.prefix = prefix; 044 } 045 046 /** 047 * Take a string (most likely a command-line argument) and try to proccess it 048 * as an option command. Return true if the string was understood, false 049 * otherwise. 050 * 051 * @param arg a String to try to process as an option command 052 * @return {@code true} if successful, {@code false} otherwise 053 */ 054 public boolean process(String arg) { 055 056 // First handle the "option commands" 057 if (arg.equals("help")) { 058 printHelp(); 059 return true; 060 } 061 if (arg.equals("printOptions")) { 062 printOptions(); 063 return true; 064 } 065 if (arg.length() == 0) { 066 printHelp(); 067 return true; 068 } 069 070 // Required format of arg is 'name=value' 071 // Split into 'name' and 'value' strings 072 int split = arg.indexOf('='); 073 if (split == -1) { 074 VM.sysWriteln(" Illegal option specification!\n \"" + arg + 075 "\" must be specified as a name-value pair in the form of option=value"); 076 return false; 077 } 078 079 String name = arg.substring(0,split); 080 String value = arg.substring(split + 1); 081 082 Option o = getOption(name); 083 084 if (o == null) return false; 085 086 switch (o.getType()) { 087 case Option.BOOLEAN_OPTION: 088 if (value.equals("true")) { 089 ((BooleanOption)o).setValue(true); 090 return true; 091 } else if (value.equals("false")) { 092 ((BooleanOption)o).setValue(false); 093 return true; 094 } 095 return false; 096 case Option.INT_OPTION: 097 int ival = CommandLineArgs.primitiveParseInt(value); 098 ((IntOption)o).setValue(ival); 099 return true; 100 case Option.ADDRESS_OPTION: 101 ival = CommandLineArgs.primitiveParseInt(value); 102 ((AddressOption)o).setValue(ival); 103 return true; 104 case Option.FLOAT_OPTION: 105 float fval = CommandLineArgs.primitiveParseFloat(value); 106 ((FloatOption)o).setValue(fval); 107 return true; 108 case Option.STRING_OPTION: 109 ((StringOption)o).setValue(value); 110 return true; 111 case Option.ENUM_OPTION: 112 ((EnumOption)o).setValue(value); 113 return true; 114 case Option.PAGES_OPTION: 115 long pval = CommandLineArgs.parseMemorySize(o.getName(), name, "b", 1, arg, value); 116 if (pval < 0) return false; 117 ((PagesOption)o).setBytes(Extent.fromIntSignExtend((int)pval)); 118 return true; 119 case Option.MICROSECONDS_OPTION: 120 int mval = CommandLineArgs.primitiveParseInt(value); 121 ((MicrosecondsOption)o).setMicroseconds(mval); 122 return true; 123 } 124 125 // None of the above tests matched, so this wasn't an option 126 return false; 127 } 128 129 /** 130 * Print a short description of every option 131 */ 132 public void printHelp() { 133 134 VM.sysWriteln("Commands"); 135 VM.sysWrite(prefix);VM.sysWriteln("[:help]\t\t\tPrint brief description of arguments"); 136 VM.sysWrite(prefix);VM.sysWriteln(":printOptions\t\tPrint the current values of options"); 137 VM.sysWriteln(); 138 139 //Begin generated help messages 140 VM.sysWrite("Boolean Options ("); 141 VM.sysWrite(prefix);VM.sysWrite(":<option>=true or "); 142 VM.sysWrite(prefix);VM.sysWriteln(":<option>=false)"); 143 VM.sysWriteln("Option Description"); 144 145 Option o = getFirst(); 146 while (o != null) { 147 if (o.getType() == Option.BOOLEAN_OPTION) { 148 String key = o.getKey(); 149 VM.sysWrite(key); 150 for (int c = key.length(); c < 39;c++) { 151 VM.sysWrite(" "); 152 } 153 VM.sysWriteln(o.getDescription()); 154 } 155 o = o.getNext(); 156 } 157 158 VM.sysWrite("\nValue Options (");VM.sysWrite(prefix);VM.sysWriteln(":<option>=<value>)"); 159 VM.sysWriteln("Option Type Description"); 160 161 o = getFirst(); 162 while (o != null) { 163 if (o.getType() != Option.BOOLEAN_OPTION && 164 o.getType() != Option.ENUM_OPTION) { 165 String key = o.getKey(); 166 VM.sysWrite(key); 167 for (int c = key.length(); c < 31;c++) { 168 VM.sysWrite(" "); 169 } 170 switch (o.getType()) { 171 case Option.INT_OPTION: VM.sysWrite("int "); break; 172 case Option.ADDRESS_OPTION: VM.sysWrite("address "); break; 173 case Option.FLOAT_OPTION: VM.sysWrite("float "); break; 174 case Option.MICROSECONDS_OPTION: VM.sysWrite("usec "); break; 175 case Option.PAGES_OPTION: VM.sysWrite("bytes "); break; 176 case Option.STRING_OPTION: VM.sysWrite("string "); break; 177 } 178 VM.sysWriteln(o.getDescription()); 179 } 180 o = o.getNext(); 181 } 182 183 VM.sysWriteln("\nSelection Options (set option to one of an enumeration of possible values)"); 184 185 o = getFirst(); 186 while (o != null) { 187 if (o.getType() == Option.ENUM_OPTION) { 188 String key = o.getKey(); 189 VM.sysWrite(key); 190 for (int c = key.length(); c < 31;c++) { 191 VM.sysWrite(" "); 192 } 193 VM.sysWriteln(o.getDescription()); 194 VM.sysWrite(" { "); 195 boolean first = true; 196 for (String val : ((EnumOption)o).getValues()) { 197 VM.sysWrite(first ? "" : ", "); 198 VM.sysWrite(val); 199 first = false; 200 } 201 VM.sysWriteln(" }"); 202 } 203 o = o.getNext(); 204 } 205 206 VM.sysExit(EXIT_STATUS_PRINTED_HELP_MESSAGE); 207 } 208 209 /** 210 * Print out the option values 211 */ 212 public void printOptions() { 213 VM.sysWriteln("Current value of GC options"); 214 215 Option o = getFirst(); 216 while (o != null) { 217 if (o.getType() == Option.BOOLEAN_OPTION) { 218 String key = o.getKey(); 219 VM.sysWrite("\t"); 220 VM.sysWrite(key); 221 for (int c = key.length(); c < 31;c++) { 222 VM.sysWrite(" "); 223 } 224 VM.sysWrite(" = "); 225 logValue(o, false); 226 VM.sysWriteln(); 227 } 228 o = o.getNext(); 229 } 230 231 o = getFirst(); 232 while (o != null) { 233 if (o.getType() != Option.BOOLEAN_OPTION && 234 o.getType() != Option.ENUM_OPTION) { 235 String key = o.getKey(); 236 VM.sysWrite("\t"); 237 VM.sysWrite(key); 238 for (int c = key.length(); c < 31;c++) { 239 VM.sysWrite(" "); 240 } 241 VM.sysWrite(" = "); 242 logValue(o, false); 243 VM.sysWriteln(); 244 } 245 o = o.getNext(); 246 } 247 248 o = getFirst(); 249 while (o != null) { 250 if (o.getType() == Option.ENUM_OPTION) { 251 String key = o.getKey(); 252 VM.sysWrite("\t"); 253 VM.sysWrite(key); 254 for (int c = key.length(); c < 31;c++) { 255 VM.sysWrite(" "); 256 } 257 VM.sysWrite(" = "); 258 logValue(o, false); 259 VM.sysWriteln(); 260 } 261 o = o.getNext(); 262 } 263 } 264 265 @Override 266 protected void logValue(Option o, boolean forXml) { 267 switch (o.getType()) { 268 case Option.BOOLEAN_OPTION: 269 VM.sysWrite(((BooleanOption) o).getValue() ? "true" : "false"); 270 break; 271 case Option.INT_OPTION: 272 VM.sysWrite(((IntOption) o).getValue()); 273 break; 274 case Option.ADDRESS_OPTION: 275 VM.sysWrite(((AddressOption) o).getValue()); 276 break; 277 case Option.FLOAT_OPTION: 278 VM.sysWrite(((FloatOption) o).getValue()); 279 break; 280 case Option.MICROSECONDS_OPTION: 281 VM.sysWrite(((MicrosecondsOption) o).getMicroseconds()); 282 VM.sysWrite(" usec"); 283 break; 284 case Option.PAGES_OPTION: 285 VM.sysWrite(((PagesOption) o).getBytes()); 286 VM.sysWrite(" bytes"); 287 break; 288 case Option.STRING_OPTION: 289 VM.sysWrite(((StringOption) o).getValue()); 290 break; 291 case Option.ENUM_OPTION: 292 VM.sysWrite(((EnumOption) o).getValueString()); 293 break; 294 } 295 } 296 297 @Override 298 protected void logString(String s) { 299 VM.sysWrite(s); 300 } 301 302 @Override 303 protected void logNewLine() { 304 VM.sysWriteln(); 305 } 306 307 @Override 308 protected String computeKey(String name) { 309 int space = name.indexOf(' '); 310 if (space < 0) return name.toLowerCase(); 311 312 String word = name.substring(0, space); 313 StringBuilder key = new StringBuilder(word.toLowerCase()); 314 315 do { 316 int old = space + 1; 317 space = name.indexOf(' ', old); 318 if (space < 0) { 319 key.append(name.substring(old)); 320 return key.toString(); 321 } 322 key.append(name.substring(old, space)); 323 } while (true); 324 } 325 326 @Override 327 protected void warn(Option o, String message) { 328 VM.sysWriteln("WARNING: Option '" + o.getKey() + "' : " + message); 329 } 330 331 @Override 332 protected void fail(Option o, String message) { 333 VM.sysFail("ERROR: Option '" + o.getKey() + "' : " + message); 334 } 335 336 @Override 337 @Uninterruptible 338 protected int bytesToPages(Extent bytes) { 339 return bytes.plus(Memory.getPagesize() - 1).toWord().rshl(Memory.getPagesizeLog()).toInt(); 340 } 341 342 @Override 343 @Uninterruptible 344 protected Extent pagesToBytes(int pages) { 345 return Word.fromIntZeroExtend(pages).lsh(Memory.getPagesizeLog()).toExtent(); 346 } 347}