src/share/vm/services/diagnosticArgument.cpp

Fri, 12 Apr 2013 15:22:08 -0700

author
katleman
date
Fri, 12 Apr 2013 15:22:08 -0700
changeset 4916
b0301c02f38e
parent 4469
c73c3f2c5b3b
child 5237
f2110083203d
permissions
-rw-r--r--

8012048: JDK8 b85 source with GPL header errors
Reviewed-by: iris, mduigou, jjg

fparain@3329 1 /*
katleman@4916 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
fparain@3329 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
fparain@3329 4 *
fparain@3329 5 * This code is free software; you can redistribute it and/or modify it
fparain@3329 6 * under the terms of the GNU General Public License version 2 only, as
fparain@3329 7 * published by the Free Software Foundation.
fparain@3329 8 *
fparain@3329 9 * This code is distributed in the hope that it will be useful, but WITHOUT
fparain@3329 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
fparain@3329 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
fparain@3329 12 * version 2 for more details (a copy is included in the LICENSE file that
fparain@3329 13 * accompanied this code).
fparain@3329 14 *
fparain@3329 15 * You should have received a copy of the GNU General Public License version
fparain@3329 16 * 2 along with this work; if not, write to the Free Software Foundation,
fparain@3329 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
fparain@3329 18 *
fparain@3329 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
fparain@3329 20 * or visit www.oracle.com if you need additional information or have any
fparain@3329 21 * questions.
fparain@3329 22 *
fparain@3329 23 */
fparain@3329 24
fparain@3329 25 #include "precompiled.hpp"
fparain@3329 26 #include "memory/allocation.inline.hpp"
fparain@3329 27 #include "runtime/thread.hpp"
fparain@3329 28 #include "services/diagnosticArgument.hpp"
fparain@3329 29
fparain@3329 30 void GenDCmdArgument::read_value(const char* str, size_t len, TRAPS) {
fparain@3559 31 /* NOTE:Some argument types doesn't require a value,
fparain@3559 32 * for instance boolean arguments: "enableFeatureX". is
fparain@3559 33 * equivalent to "enableFeatureX=true". In these cases,
fparain@3559 34 * str will be null. This is perfectly valid.
fparain@3559 35 * All argument types must perform null checks on str.
fparain@3559 36 */
fparain@3559 37
fparain@3559 38 if (is_set() && !allow_multiple()) {
fparain@3329 39 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 40 "Duplicates in diagnostic command arguments\n");
fparain@3329 41 }
fparain@3329 42 parse_value(str, len, CHECK);
fparain@3329 43 set_is_set(true);
fparain@3329 44 }
fparain@3329 45
nloodin@3681 46 void GenDCmdArgument::to_string(jlong l, char* buf, size_t len) {
nloodin@3681 47 jio_snprintf(buf, len, INT64_FORMAT, l);
nloodin@3681 48 }
nloodin@3681 49
nloodin@3681 50 void GenDCmdArgument::to_string(bool b, char* buf, size_t len) {
nloodin@3681 51 jio_snprintf(buf, len, b ? "true" : "false");
nloodin@3681 52 }
nloodin@3681 53
nloodin@3681 54 void GenDCmdArgument::to_string(NanoTimeArgument n, char* buf, size_t len) {
nloodin@3681 55 jio_snprintf(buf, len, INT64_FORMAT, n._nanotime);
nloodin@3681 56 }
nloodin@3681 57
nloodin@3681 58 void GenDCmdArgument::to_string(MemorySizeArgument m, char* buf, size_t len) {
nloodin@3681 59 jio_snprintf(buf, len, INT64_FORMAT, m._size);
nloodin@3681 60 }
nloodin@3681 61
nloodin@3681 62 void GenDCmdArgument::to_string(char* c, char* buf, size_t len) {
nloodin@3681 63 jio_snprintf(buf, len, "%s", c);
nloodin@3681 64 }
nloodin@3681 65
nloodin@3681 66 void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) {
nloodin@3681 67 int length = f->array()->length();
nloodin@3681 68 size_t written = 0;
nloodin@3681 69 buf[0] = 0;
nloodin@3681 70 for (int i = 0; i < length; i++) {
nloodin@3681 71 char* next_str = f->array()->at(i);
nloodin@3681 72 size_t next_size = strlen(next_str);
nloodin@3681 73 //Check if there's room left to write next element
nloodin@3681 74 if (written + next_size > len) {
nloodin@3681 75 return;
nloodin@3681 76 }
nloodin@3681 77 //Actually write element
nloodin@3681 78 strcat(buf, next_str);
nloodin@3681 79 written += next_size;
nloodin@3681 80 //Check if there's room left for the comma
nloodin@3681 81 if (i < length-1 && len - written > 0) {
nloodin@3681 82 strcat(buf, ",");
nloodin@3681 83 }
nloodin@3681 84 }
nloodin@3681 85 }
nloodin@3681 86
fparain@3329 87 template <> void DCmdArgument<jlong>::parse_value(const char* str,
fparain@3329 88 size_t len, TRAPS) {
hseigel@4465 89 if (str == NULL || sscanf(str, JLONG_FORMAT, &_value) != 1) {
fparain@3329 90 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 91 "Integer parsing error in diagnostic command arguments\n");
fparain@3329 92 }
fparain@3329 93 }
fparain@3329 94
fparain@3329 95 template <> void DCmdArgument<jlong>::init_value(TRAPS) {
fparain@3329 96 if (has_default()) {
fparain@3329 97 this->parse_value(_default_string, strlen(_default_string), THREAD);
fparain@3329 98 if (HAS_PENDING_EXCEPTION) {
fparain@3329 99 fatal("Default string must be parsable");
fparain@3329 100 }
fparain@3329 101 } else {
fparain@3329 102 set_value(0);
fparain@3329 103 }
fparain@3329 104 }
fparain@3329 105
fparain@3329 106 template <> void DCmdArgument<jlong>::destroy_value() { }
fparain@3329 107
fparain@3329 108 template <> void DCmdArgument<bool>::parse_value(const char* str,
fparain@3329 109 size_t len, TRAPS) {
fparain@3476 110 // len is the length of the current token starting at str
fparain@3329 111 if (len == 0) {
fparain@3329 112 set_value(true);
fparain@3329 113 } else {
fparain@3476 114 if (len == strlen("true") && strncasecmp(str, "true", len) == 0) {
fparain@3329 115 set_value(true);
fparain@3476 116 } else if (len == strlen("false") && strncasecmp(str, "false", len) == 0) {
fparain@3329 117 set_value(false);
fparain@3329 118 } else {
fparain@3329 119 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3329 120 "Boolean parsing error in diagnostic command arguments");
fparain@3329 121 }
fparain@3329 122 }
fparain@3329 123 }
fparain@3329 124
fparain@3329 125 template <> void DCmdArgument<bool>::init_value(TRAPS) {
fparain@3329 126 if (has_default()) {
fparain@3329 127 this->parse_value(_default_string, strlen(_default_string), THREAD);
fparain@3329 128 if (HAS_PENDING_EXCEPTION) {
fparain@3329 129 fatal("Default string must be parsable");
fparain@3329 130 }
fparain@3329 131 } else {
fparain@3329 132 set_value(false);
fparain@3329 133 }
fparain@3329 134 }
fparain@3329 135
fparain@3329 136 template <> void DCmdArgument<bool>::destroy_value() { }
fparain@3329 137
fparain@3329 138 template <> void DCmdArgument<char*>::parse_value(const char* str,
fparain@3329 139 size_t len, TRAPS) {
fparain@3559 140 if (str == NULL) {
fparain@3559 141 _value = NULL;
fparain@3559 142 } else {
zgu@3900 143 _value = NEW_C_HEAP_ARRAY(char, len+1, mtInternal);
fparain@3559 144 strncpy(_value, str, len);
fparain@3559 145 _value[len] = 0;
fparain@3559 146 }
fparain@3329 147 }
fparain@3329 148
fparain@3329 149 template <> void DCmdArgument<char*>::init_value(TRAPS) {
fparain@3559 150 if (has_default() && _default_string != NULL) {
fparain@3329 151 this->parse_value(_default_string, strlen(_default_string), THREAD);
fparain@3329 152 if (HAS_PENDING_EXCEPTION) {
fparain@3559 153 fatal("Default string must be parsable");
fparain@3329 154 }
fparain@3329 155 } else {
fparain@3329 156 set_value(NULL);
fparain@3329 157 }
fparain@3329 158 }
fparain@3329 159
fparain@3329 160 template <> void DCmdArgument<char*>::destroy_value() {
fparain@3329 161 if (_value != NULL) {
zgu@3900 162 FREE_C_HEAP_ARRAY(char, _value, mtInternal);
fparain@3329 163 set_value(NULL);
fparain@3329 164 }
fparain@3329 165 }
fparain@3559 166
fparain@3559 167 template <> void DCmdArgument<NanoTimeArgument>::parse_value(const char* str,
fparain@3559 168 size_t len, TRAPS) {
fparain@3559 169 if (str == NULL) {
fparain@3559 170 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 171 "Integer parsing error nanotime value: syntax error");
fparain@3559 172 }
fparain@3559 173
hseigel@4465 174 int argc = sscanf(str, JLONG_FORMAT, &_value._time);
fparain@3559 175 if (argc != 1) {
fparain@3559 176 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 177 "Integer parsing error nanotime value: syntax error");
fparain@3559 178 }
fparain@3559 179 size_t idx = 0;
fparain@3559 180 while(idx < len && isdigit(str[idx])) {
fparain@3559 181 idx++;
fparain@3559 182 }
fparain@3559 183 if (idx == len) {
fparain@3559 184 // only accept missing unit if the value is 0
fparain@3559 185 if (_value._time != 0) {
fparain@3559 186 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 187 "Integer parsing error nanotime value: unit required");
fparain@3559 188 } else {
fparain@3559 189 _value._nanotime = 0;
fparain@3559 190 strcpy(_value._unit, "ns");
fparain@3559 191 return;
fparain@3559 192 }
fparain@3559 193 } else if(len - idx > 2) {
fparain@3559 194 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 195 "Integer parsing error nanotime value: illegal unit");
fparain@3559 196 } else {
fparain@3559 197 strncpy(_value._unit, &str[idx], len - idx);
fparain@3559 198 /*Write an extra null termination. This is safe because _value._unit
fparain@3559 199 * is declared as char[3], and length is checked to be not larger than
fparain@3559 200 * two above. Also, this is necessary, since length might be 1, and the
fparain@3559 201 * default value already in the string is ns, which is two chars.
fparain@3559 202 */
fparain@3559 203 _value._unit[len-idx] = '\0';
fparain@3559 204 }
fparain@3559 205
fparain@3559 206 if (strcmp(_value._unit, "ns") == 0) {
fparain@3559 207 _value._nanotime = _value._time;
fparain@3559 208 } else if (strcmp(_value._unit, "us") == 0) {
fparain@3559 209 _value._nanotime = _value._time * 1000;
fparain@3559 210 } else if (strcmp(_value._unit, "ms") == 0) {
fparain@3559 211 _value._nanotime = _value._time * 1000 * 1000;
fparain@3559 212 } else if (strcmp(_value._unit, "s") == 0) {
fparain@3559 213 _value._nanotime = _value._time * 1000 * 1000 * 1000;
fparain@3559 214 } else if (strcmp(_value._unit, "m") == 0) {
fparain@3559 215 _value._nanotime = _value._time * 60 * 1000 * 1000 * 1000;
fparain@3559 216 } else if (strcmp(_value._unit, "h") == 0) {
fparain@3559 217 _value._nanotime = _value._time * 60 * 60 * 1000 * 1000 * 1000;
fparain@3559 218 } else if (strcmp(_value._unit, "d") == 0) {
fparain@3559 219 _value._nanotime = _value._time * 24 * 60 * 60 * 1000 * 1000 * 1000;
fparain@3559 220 } else {
fparain@3559 221 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 222 "Integer parsing error nanotime value: illegal unit");
fparain@3559 223 }
fparain@3559 224 }
fparain@3559 225
fparain@3559 226 template <> void DCmdArgument<NanoTimeArgument>::init_value(TRAPS) {
fparain@3559 227 if (has_default()) {
fparain@3559 228 this->parse_value(_default_string, strlen(_default_string), THREAD);
fparain@3559 229 if (HAS_PENDING_EXCEPTION) {
fparain@3559 230 fatal("Default string must be parsable");
fparain@3559 231 }
fparain@3559 232 } else {
fparain@3559 233 _value._time = 0;
fparain@3559 234 _value._nanotime = 0;
fparain@3559 235 strcmp(_value._unit, "ns");
fparain@3559 236 }
fparain@3559 237 }
fparain@3559 238
fparain@3559 239 template <> void DCmdArgument<NanoTimeArgument>::destroy_value() { }
fparain@3559 240
fparain@3559 241 // WARNING StringArrayArgument can only be used as an option, it cannot be
fparain@3559 242 // used as an argument with the DCmdParser
fparain@3559 243
fparain@3559 244 template <> void DCmdArgument<StringArrayArgument*>::parse_value(const char* str,
fparain@3559 245 size_t len, TRAPS) {
fparain@3559 246 _value->add(str,len);
fparain@3559 247 }
fparain@3559 248
fparain@3559 249 template <> void DCmdArgument<StringArrayArgument*>::init_value(TRAPS) {
fparain@3559 250 _value = new StringArrayArgument();
fparain@3559 251 _allow_multiple = true;
fparain@3559 252 if (has_default()) {
fparain@3559 253 fatal("StringArrayArgument cannot have default value");
fparain@3559 254 }
fparain@3559 255 }
fparain@3559 256
fparain@3559 257 template <> void DCmdArgument<StringArrayArgument*>::destroy_value() {
fparain@3559 258 if (_value != NULL) {
fparain@3559 259 delete _value;
fparain@3559 260 set_value(NULL);
fparain@3559 261 }
fparain@3559 262 }
fparain@3559 263
fparain@3559 264 template <> void DCmdArgument<MemorySizeArgument>::parse_value(const char* str,
fparain@3559 265 size_t len, TRAPS) {
fparain@3559 266 if (str == NULL) {
fparain@3559 267 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 268 "Integer parsing error nanotime value: syntax error");
fparain@3559 269 }
fparain@3559 270
fparain@3559 271 if (*str == '-') {
fparain@3559 272 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 273 "Parsing error memory size value: negative values not allowed");
fparain@3559 274 }
fparain@3559 275 int res = sscanf(str, UINT64_FORMAT "%c", &_value._val, &_value._multiplier);
fparain@3559 276 if (res == 2) {
fparain@3559 277 switch (_value._multiplier) {
fparain@3559 278 case 'k': case 'K':
fparain@3559 279 _value._size = _value._val * 1024;
fparain@3559 280 break;
fparain@3559 281 case 'm': case 'M':
fparain@3559 282 _value._size = _value._val * 1024 * 1024;
fparain@3559 283 break;
fparain@3559 284 case 'g': case 'G':
fparain@3559 285 _value._size = _value._val * 1024 * 1024 * 1024;
fparain@3559 286 break;
fparain@3559 287 default:
fparain@3559 288 _value._size = _value._val;
fparain@3559 289 _value._multiplier = ' ';
fparain@3559 290 //default case should be to break with no error, since user
fparain@3559 291 //can write size in bytes, or might have a delimiter and next arg
fparain@3559 292 break;
fparain@3559 293 }
fparain@3559 294 } else if (res == 1) {
fparain@3559 295 _value._size = _value._val;
fparain@3559 296 } else {
fparain@3559 297 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
fparain@3559 298 "Parsing error memory size value: invalid value");
fparain@3559 299 }
fparain@3559 300 }
fparain@3559 301
fparain@3559 302 template <> void DCmdArgument<MemorySizeArgument>::init_value(TRAPS) {
fparain@3559 303 if (has_default()) {
fparain@3559 304 this->parse_value(_default_string, strlen(_default_string), THREAD);
fparain@3559 305 if (HAS_PENDING_EXCEPTION) {
fparain@3559 306 fatal("Default string must be parsable");
fparain@3559 307 }
fparain@3559 308 } else {
fparain@3559 309 _value._size = 0;
fparain@3559 310 _value._val = 0;
fparain@3559 311 _value._multiplier = ' ';
fparain@3559 312 }
fparain@3559 313 }
fparain@3559 314
fparain@3559 315 template <> void DCmdArgument<MemorySizeArgument>::destroy_value() { }

mercurial