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

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

mercurial