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