src/share/vm/services/diagnosticArgument.cpp

Print this page
rev 4773 : 8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>


   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  */
  24 
  25 #include "precompiled.hpp"
  26 #include "memory/allocation.inline.hpp"

  27 #include "runtime/thread.hpp"
  28 #include "services/diagnosticArgument.hpp"
  29 
  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    */
  37 
  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 }
  45 
  46 void GenDCmdArgument::to_string(jlong l, char* buf, size_t len) {


  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 }
  86 
  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 }
  94 
  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 }
 105 
 106 template <> void DCmdArgument<jlong>::destroy_value() { }
 107 
 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 }
 124 
 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 }
 135 
 136 template <> void DCmdArgument<bool>::destroy_value() { }
 137 
 138 template <> void DCmdArgument<char*>::parse_value(const char* str,
 139                                                   size_t len, TRAPS) {
 140   if (str == 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 }
 159 
 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 }
 166 
 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   }
 173 
 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;




   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  */
  24 
  25 #include "precompiled.hpp"
  26 #include "memory/allocation.inline.hpp"
  27 #include "memory/resourceArea.hpp"
  28 #include "runtime/thread.hpp"
  29 #include "services/diagnosticArgument.hpp"
  30 
  31 void GenDCmdArgument::read_value(const char* str, size_t len, TRAPS) {
  32   /* NOTE:Some argument types doesn't require a value,
  33    * for instance boolean arguments: "enableFeatureX". is
  34    * equivalent to "enableFeatureX=true". In these cases,
  35    * str will be null. This is perfectly valid.
  36    * All argument types must perform null checks on str.
  37    */
  38 
  39   if (is_set() && !allow_multiple()) {
  40     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
  41             "Duplicates in diagnostic command arguments\n");
  42   }
  43   parse_value(str, len, CHECK);
  44   set_is_set(true);
  45 }
  46 
  47 void GenDCmdArgument::to_string(jlong l, char* buf, size_t len) {


  70   buf[0] = 0;
  71   for (int i = 0; i < length; i++) {
  72     char* next_str = f->array()->at(i);
  73     size_t next_size = strlen(next_str);
  74     //Check if there's room left to write next element
  75     if (written + next_size > len) {
  76       return;
  77     }
  78     //Actually write element
  79     strcat(buf, next_str);
  80     written += next_size;
  81     //Check if there's room left for the comma
  82     if (i < length-1 && len - written > 0) {
  83       strcat(buf, ",");
  84     }
  85   }
  86 }
  87 
  88 template <> void DCmdArgument<jlong>::parse_value(const char* str,
  89                                                   size_t len, TRAPS) {
  90   int scanned = -1;
  91   if (str == NULL
  92       || sscanf(str, JLONG_FORMAT"%n", &_value, &scanned) != 1
  93       || (size_t)scanned != len)
  94   {
  95     ResourceMark rm;
  96 
  97     char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
  98     strncpy(buf, str, len);
  99     buf[len] = '\0';
 100     Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),
 101       "Integer parsing error in command argument '%s'. Could not parse: %s.", _name, buf);
 102   }
 103 }
 104 
 105 template <> void DCmdArgument<jlong>::init_value(TRAPS) {
 106   if (has_default()) {
 107     this->parse_value(_default_string, strlen(_default_string), THREAD);
 108     if (HAS_PENDING_EXCEPTION) {
 109       fatal("Default string must be parseable");
 110     }
 111   } else {
 112     set_value(0);
 113   }
 114 }
 115 
 116 template <> void DCmdArgument<jlong>::destroy_value() { }
 117 
 118 template <> void DCmdArgument<bool>::parse_value(const char* str,
 119                                                  size_t len, TRAPS) {
 120   // len is the length of the current token starting at str
 121   if (len == 0) {
 122     set_value(true);
 123   } else {
 124     if (len == strlen("true") && strncasecmp(str, "true", len) == 0) {
 125        set_value(true);
 126     } else if (len == strlen("false") && strncasecmp(str, "false", len) == 0) {
 127        set_value(false);
 128     } else {
 129       ResourceMark rm;
 130 
 131       char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
 132       strncpy(buf, str, len);
 133       buf[len] = '\0';
 134       Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),
 135         "Boolean parsing error in command argument '%s'. Could not parse: %s.", _name, buf);
 136     }
 137   }
 138 }
 139 
 140 template <> void DCmdArgument<bool>::init_value(TRAPS) {
 141   if (has_default()) {
 142     this->parse_value(_default_string, strlen(_default_string), THREAD);
 143     if (HAS_PENDING_EXCEPTION) {
 144       fatal("Default string must be parsable");
 145     }
 146   } else {
 147     set_value(false);
 148   }
 149 }
 150 
 151 template <> void DCmdArgument<bool>::destroy_value() { }
 152 
 153 template <> void DCmdArgument<char*>::parse_value(const char* str,
 154                                                   size_t len, TRAPS) {
 155   if (str == NULL) {


 166     this->parse_value(_default_string, strlen(_default_string), THREAD);
 167     if (HAS_PENDING_EXCEPTION) {
 168      fatal("Default string must be parsable");
 169     }
 170   } else {
 171     set_value(NULL);
 172   }
 173 }
 174 
 175 template <> void DCmdArgument<char*>::destroy_value() {
 176   if (_value != NULL) {
 177     FREE_C_HEAP_ARRAY(char, _value, mtInternal);
 178     set_value(NULL);
 179   }
 180 }
 181 
 182 template <> void DCmdArgument<NanoTimeArgument>::parse_value(const char* str,
 183                                                  size_t len, TRAPS) {
 184   if (str == NULL) {
 185     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
 186               "Integer parsing error nanotime value: syntax error, value is null");
 187   }
 188 
 189   int argc = sscanf(str, JLONG_FORMAT, &_value._time);
 190   if (argc != 1) {
 191     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
 192               "Integer parsing error nanotime value: syntax error");
 193   }
 194   size_t idx = 0;
 195   while(idx < len && isdigit(str[idx])) {
 196     idx++;
 197   }
 198   if (idx == len) {
 199     // only accept missing unit if the value is 0
 200     if (_value._time != 0) {
 201       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
 202                 "Integer parsing error nanotime value: unit required");
 203     } else {
 204       _value._nanotime = 0;
 205       strcpy(_value._unit, "ns");
 206       return;