globals.cpp revision 342:37f87013dfd8
115103Sphk/*
215103Sphk * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
315103Sphk * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
415103Sphk *
515103Sphk * This code is free software; you can redistribute it and/or modify it
615103Sphk * under the terms of the GNU General Public License version 2 only, as
715103Sphk * published by the Free Software Foundation.
815103Sphk *
915103Sphk * This code is distributed in the hope that it will be useful, but WITHOUT
1015103Sphk * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1115103Sphk * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1215103Sphk * version 2 for more details (a copy is included in the LICENSE file that
1315103Sphk * accompanied this code).
1415103Sphk *
1515103Sphk * You should have received a copy of the GNU General Public License version
1615103Sphk * 2 along with this work; if not, write to the Free Software Foundation,
1715103Sphk * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1815103Sphk *
1915103Sphk * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
2015103Sphk * CA 95054 USA or visit www.sun.com if you need additional information or
2115103Sphk * have any questions.
2215103Sphk *
2315103Sphk */
2415103Sphk
2515103Sphk# include "incls/_precompiled.incl"
2615103Sphk# include "incls/_globals.cpp.incl"
2715103Sphk
2815103Sphk
2915103SphkRUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \
3015103Sphk              MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
3115103Sphk              MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG, \
3215103Sphk              MATERIALIZE_MANAGEABLE_FLAG, MATERIALIZE_PRODUCT_RW_FLAG, \
3315103Sphk              MATERIALIZE_LP64_PRODUCT_FLAG)
3415103Sphk
3515103SphkRUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \
3615103Sphk                 MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
3715103Sphk                 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
3815103Sphk
3915103Sphkbool Flag::is_unlocker() const {
4050477Speter  return strcmp(name, "UnlockDiagnosticVMOptions") == 0;
4115103Sphk}
4215103Sphk
4384611Srwatsonbool Flag::is_unlocked() const {
4484611Srwatson  if (strcmp(kind, "{diagnostic}") == 0) {
4515103Sphk    return UnlockDiagnosticVMOptions;
4615103Sphk  } else {
4715103Sphk    return true;
4815103Sphk  }
4915103Sphk}
5046155Sphk
5176078Sjhbbool Flag::is_writeable() const {
5228918Skato  return (strcmp(kind, "{manageable}") == 0 || strcmp(kind, "{product rw}") == 0);
5315103Sphk}
5415103Sphk
5515103Sphk// All flags except "manageable" are assumed internal flags.
5615103Sphk// Long term, we need to define a mechanism to specify which flags
5715103Sphk// are external/stable and change this function accordingly.
5815103Sphkbool Flag::is_external() const {
5923382Sbde  return (strcmp(kind, "{manageable}") == 0);
6015103Sphk}
6115103Sphk
6215103Sphk// Length of format string (e.g. "%.1234s") for printing ccstr below
6315103Sphk#define FORMAT_BUFFER_LEN 16
6415103Sphk
6548891Sphkvoid Flag::print_on(outputStream* st) {
6648891Sphk  st->print("%5s %-35s %c= ", type, name, (origin != DEFAULT ? ':' : ' '));
6715103Sphk  if (is_bool())  st->print("%-16s", get_bool() ? "true" : "false");
6815103Sphk  if (is_intx())  st->print("%-16ld", get_intx());
6915103Sphk  if (is_uintx()) st->print("%-16lu", get_uintx());
7015103Sphk  if (is_ccstr()) {
7115103Sphk    const char* cp = get_ccstr();
7215103Sphk    if (cp != NULL) {
7334925Sdufault      const char* eol;
7434925Sdufault      while ((eol = strchr(cp, '\n')) != NULL) {
7534029Sdufault        char format_buffer[FORMAT_BUFFER_LEN];
7650465Smarcel        size_t llen = pointer_delta(eol, cp, sizeof(char));
7750465Smarcel        jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
7850465Smarcel                     "%%." SIZE_FORMAT "s", llen);
7946381Sbillf        st->print(format_buffer, cp);
8046381Sbillf        st->cr();
8115103Sphk        cp = eol+1;
8246381Sbillf        st->print("%5s %-35s += ", "", name);
8346381Sbillf      }
8415103Sphk      st->print("%-16s", cp);
8546381Sbillf    }
8646381Sbillf  }
8715103Sphk  st->print(" %s", kind);
8846381Sbillf  st->cr();
8946381Sbillf}
9015103Sphk
9115103Sphkvoid Flag::print_as_flag(outputStream* st) {
9246381Sbillf  if (is_bool()) {
9346381Sbillf    st->print("-XX:%s%s", get_bool() ? "+" : "-", name);
9415103Sphk  } else if (is_intx()) {
9546381Sbillf    st->print("-XX:%s=" INTX_FORMAT, name, get_intx());
9646381Sbillf  } else if (is_uintx()) {
9715103Sphk    st->print("-XX:%s=" UINTX_FORMAT, name, get_uintx());
9846381Sbillf  } else if (is_ccstr()) {
9946381Sbillf    st->print("-XX:%s=", name);
10015103Sphk    const char* cp = get_ccstr();
10180447Speter    if (cp != NULL) {
10280418Speter      // Need to turn embedded '\n's back into separate arguments
10380418Speter      // Not so efficient to print one character at a time,
10446381Sbillf      // but the choice is to do the transformation to a buffer
10546381Sbillf      // and print that.  And this need not be efficient.
10615103Sphk      for (; *cp != '\0'; cp += 1) {
10746381Sbillf        switch (*cp) {
10846381Sbillf          default:
10915103Sphk            st->print("%c", *cp);
11046381Sbillf            break;
11146381Sbillf          case '\n':
11215103Sphk            st->print(" -XX:%s=", name);
11346381Sbillf            break;
11446381Sbillf        }
11515103Sphk      }
11615103Sphk    }
11746381Sbillf  } else {
11846381Sbillf    ShouldNotReachHere();
11915103Sphk  }
12046381Sbillf}
12146381Sbillf
12215103Sphk// 4991491 do not "optimize out" the was_set false values: omitting them
12315103Sphk// tickles a Microsoft compiler bug causing flagTable to be malformed
12415103Sphk
12515103Sphk#define RUNTIME_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{product}", DEFAULT },
12646381Sbillf#define RUNTIME_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{pd product}", DEFAULT },
12746381Sbillf#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{diagnostic}", DEFAULT },
12815103Sphk#define RUNTIME_MANAGEABLE_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{manageable}", DEFAULT },
12931990Sgpalmer#define RUNTIME_PRODUCT_RW_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{product rw}", DEFAULT },
13046381Sbillf
13146381Sbillf#ifdef PRODUCT
13231990Sgpalmer  #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
13346381Sbillf  #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
13446381Sbillf  #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
13531990Sgpalmer#else
13615103Sphk  #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "", DEFAULT },
13746381Sbillf  #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{pd}", DEFAULT },
13846381Sbillf  #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{notproduct}", DEFAULT },
13915103Sphk#endif
14046381Sbillf
14146381Sbillf#ifdef _LP64
14215103Sphk  #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{lp64_product}", DEFAULT },
14328885Skato#else
14428885Skato  #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
14546381Sbillf#endif // _LP64
14628885Skato
14784611Srwatson#define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C1 product}", DEFAULT },
14884611Srwatson#define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{C1 pd product}", DEFAULT },
14984611Srwatson#ifdef PRODUCT
15084611Srwatson  #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
15115103Sphk  #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
15215103Sphk  #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
15346155Sphk#else
15462573Sphk  #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C1}", DEFAULT },
15546155Sphk  #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{C1 pd}", DEFAULT },
15646155Sphk  #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C1 notproduct}", DEFAULT },
15715103Sphk#endif
15872786Srwatson
15957163Srwatson
16057111Srwatson#define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 product}", DEFAULT },
16146155Sphk#define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{C2 pd product}", DEFAULT },
16272786Srwatson#define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 diagnostic}", DEFAULT },
16372786Srwatson#ifdef PRODUCT
16457111Srwatson  #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
16546155Sphk  #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
16646155Sphk  #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
16746155Sphk#else
16846155Sphk  #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2}", DEFAULT },
16946155Sphk  #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{C2 pd}", DEFAULT },
17046155Sphk  #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 notproduct}", DEFAULT },
17146155Sphk#endif
17246381Sbillf
17346155Sphk
17484611Srwatsonstatic Flag flagTable[] = {
17584611Srwatson RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT)
17684611Srwatson RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT)
17784611Srwatson#ifndef SERIALGC
17884611Srwatson G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT)
17984611Srwatson#endif // SERIALGC
18084611Srwatson#ifdef COMPILER1
18115103Sphk C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT)
18215103Sphk#endif
18315103Sphk#ifdef COMPILER2
18462573Sphk C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT)
18515103Sphk#endif
18615103Sphk {0, NULL, NULL}
18715103Sphk};
18883990Srwatson
18983990SrwatsonFlag* Flag::flags = flagTable;
19083990Srwatsonsize_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
19183990Srwatson
19283990Srwatsoninline bool str_equal(const char* s, char* q, size_t len) {
19383990Srwatson  // s is null terminated, q is not!
19483990Srwatson  if (strlen(s) != (unsigned int) len) return false;
19583990Srwatson  return strncmp(s, q, len) == 0;
19683990Srwatson}
19783990Srwatson
19815103SphkFlag* Flag::find_flag(char* name, size_t length) {
19915103Sphk  for (Flag* current = &flagTable[0]; current->name; current++) {
20015103Sphk    if (str_equal(current->name, name, length)) {
20183990Srwatson      if (!(current->is_unlocked() || current->is_unlocker())) {
20283990Srwatson        // disable use of diagnostic flags until they are unlocked
20383990Srwatson        return NULL;
20483990Srwatson      }
20583990Srwatson      return current;
20684611Srwatson    }
20784611Srwatson  }
20884611Srwatson  return NULL;
20983990Srwatson}
21083990Srwatson
21183990Srwatson// Returns the address of the index'th element
21283990Srwatsonstatic Flag* address_of_flag(CommandLineFlagWithType flag) {
21383990Srwatson  assert((size_t)flag < Flag::numFlags, "bad command line flag index");
21484611Srwatson  return &Flag::flags[flag];
21584611Srwatson}
21684611Srwatson
21783990Srwatsonbool CommandLineFlagsEx::is_default(CommandLineFlag flag) {
21883990Srwatson  assert((size_t)flag < Flag::numFlags, "bad command line flag index");
21983990Srwatson  Flag* f = &Flag::flags[flag];
22083990Srwatson  return (f->origin == DEFAULT);
22115103Sphk}
22215103Sphk
22315103Sphkbool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) {
22483990Srwatson  assert((size_t)flag < Flag::numFlags, "bad command line flag index");
22583990Srwatson  Flag* f = &Flag::flags[flag];
22683990Srwatson  return (f->origin == ERGONOMIC);
22761370Srwatson}
22815103Sphk
22917281Swollmanbool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) {
23046381Sbillf  assert((size_t)flag < Flag::numFlags, "bad command line flag index");
23115103Sphk  Flag* f = &Flag::flags[flag];
23278609Spirzyk  return (f->origin == COMMAND_LINE);
23378609Spirzyk}
23415103Sphk
23515103Sphkbool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
23615103Sphk  Flag* result = Flag::find_flag((char*)name, strlen(name));
23715103Sphk  if (result == NULL) return false;
23815103Sphk  *value = (result->origin == COMMAND_LINE);
23915103Sphk  return true;
24046381Sbillf}
24146381Sbillf
24246381Sbillfbool CommandLineFlags::boolAt(char* name, size_t len, bool* value) {
24346381Sbillf  Flag* result = Flag::find_flag(name, len);
24446381Sbillf  if (result == NULL) return false;
24546381Sbillf  if (!result->is_bool()) return false;
24646381Sbillf  *value = result->get_bool();
24746381Sbillf  return true;
24846381Sbillf}
24946381Sbillf
25046381Sbillfbool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin) {
25146381Sbillf  Flag* result = Flag::find_flag(name, len);
25218540Sbde  if (result == NULL) return false;
25346381Sbillf  if (!result->is_bool()) return false;
25446381Sbillf  bool old_value = result->get_bool();
25546381Sbillf  result->set_bool(*value);
25646381Sbillf  *value = old_value;
25746381Sbillf  result->origin = origin;
25846381Sbillf  return true;
25946381Sbillf}
26046381Sbillf
26146381Sbillfvoid CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin) {
26246381Sbillf  Flag* faddr = address_of_flag(flag);
26346381Sbillf  guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
26446381Sbillf  faddr->set_bool(value);
26546381Sbillf  faddr->origin = origin;
26646381Sbillf}
26746381Sbillf
26846381Sbillfbool CommandLineFlags::intxAt(char* name, size_t len, intx* value) {
26946381Sbillf  Flag* result = Flag::find_flag(name, len);
27046381Sbillf  if (result == NULL) return false;
27146381Sbillf  if (!result->is_intx()) return false;
27246381Sbillf  *value = result->get_intx();
27346381Sbillf  return true;
27446381Sbillf}
27546381Sbillf
27646381Sbillfbool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin) {
27746381Sbillf  Flag* result = Flag::find_flag(name, len);
27846381Sbillf  if (result == NULL) return false;
27946381Sbillf  if (!result->is_intx()) return false;
28048891Sphk  intx old_value = result->get_intx();
28148891Sphk  result->set_intx(*value);
28248891Sphk  *value = old_value;
28348891Sphk  result->origin = origin;
28448891Sphk  return true;
28548891Sphk}
28648891Sphk
28748927Sphkvoid CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin) {
28849535Sphk  Flag* faddr = address_of_flag(flag);
28948927Sphk  guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
29048927Sphk  faddr->set_intx(value);
29158926Sphk  faddr->origin = origin;
29260041Sphk}
29358926Sphk
29458926Sphkbool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) {
29558926Sphk  Flag* result = Flag::find_flag(name, len);
29658926Sphk  if (result == NULL) return false;
29758926Sphk  if (!result->is_uintx()) return false;
29872376Sjake  *value = result->get_uintx();
29972376Sjake  return true;
30072376Sjake}
30172376Sjake
302bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin) {
303  Flag* result = Flag::find_flag(name, len);
304  if (result == NULL) return false;
305  if (!result->is_uintx()) return false;
306  uintx old_value = result->get_uintx();
307  result->set_uintx(*value);
308  *value = old_value;
309  result->origin = origin;
310  return true;
311}
312
313void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin) {
314  Flag* faddr = address_of_flag(flag);
315  guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
316  faddr->set_uintx(value);
317  faddr->origin = origin;
318}
319
320bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) {
321  Flag* result = Flag::find_flag(name, len);
322  if (result == NULL) return false;
323  if (!result->is_double()) return false;
324  *value = result->get_double();
325  return true;
326}
327
328bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin) {
329  Flag* result = Flag::find_flag(name, len);
330  if (result == NULL) return false;
331  if (!result->is_double()) return false;
332  double old_value = result->get_double();
333  result->set_double(*value);
334  *value = old_value;
335  result->origin = origin;
336  return true;
337}
338
339void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin) {
340  Flag* faddr = address_of_flag(flag);
341  guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
342  faddr->set_double(value);
343  faddr->origin = origin;
344}
345
346bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) {
347  Flag* result = Flag::find_flag(name, len);
348  if (result == NULL) return false;
349  if (!result->is_ccstr()) return false;
350  *value = result->get_ccstr();
351  return true;
352}
353
354// Contract:  Flag will make private copy of the incoming value.
355// Outgoing value is always malloc-ed, and caller MUST call free.
356bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin) {
357  Flag* result = Flag::find_flag(name, len);
358  if (result == NULL) return false;
359  if (!result->is_ccstr()) return false;
360  ccstr old_value = result->get_ccstr();
361  char* new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1);
362  strcpy(new_value, *value);
363  result->set_ccstr(new_value);
364  if (result->origin == DEFAULT && old_value != NULL) {
365    // Prior value is NOT heap allocated, but was a literal constant.
366    char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1);
367    strcpy(old_value_to_free, old_value);
368    old_value = old_value_to_free;
369  }
370  *value = old_value;
371  result->origin = origin;
372  return true;
373}
374
375// Contract:  Flag will make private copy of the incoming value.
376void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin) {
377  Flag* faddr = address_of_flag(flag);
378  guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
379  ccstr old_value = faddr->get_ccstr();
380  char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1);
381  strcpy(new_value, value);
382  faddr->set_ccstr(new_value);
383  if (faddr->origin != DEFAULT && old_value != NULL) {
384    // Prior value is heap allocated so free it.
385    FREE_C_HEAP_ARRAY(char, old_value);
386  }
387  faddr->origin = origin;
388}
389
390extern "C" {
391  static int compare_flags(const void* void_a, const void* void_b) {
392    return strcmp((*((Flag**) void_a))->name, (*((Flag**) void_b))->name);
393  }
394}
395
396void CommandLineFlags::printSetFlags() {
397  // Print which flags were set on the command line
398  // note: this method is called before the thread structure is in place
399  //       which means resource allocation cannot be used.
400
401  // Compute size
402  int length= 0;
403  while (flagTable[length].name != NULL) length++;
404
405  // Sort
406  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length);
407  for (int index = 0; index < length; index++) {
408    array[index] = &flagTable[index];
409  }
410  qsort(array, length, sizeof(Flag*), compare_flags);
411
412  // Print
413  for (int i = 0; i < length; i++) {
414    if (array[i]->origin /* naked field! */) {
415      array[i]->print_as_flag(tty);
416      tty->print(" ");
417    }
418  }
419  tty->cr();
420  FREE_C_HEAP_ARRAY(Flag*, array);
421}
422
423#ifndef PRODUCT
424
425
426void CommandLineFlags::verify() {
427  assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict");
428}
429
430void CommandLineFlags::printFlags() {
431  // Print the flags sorted by name
432  // note: this method is called before the thread structure is in place
433  //       which means resource allocation cannot be used.
434
435  // Compute size
436  int length= 0;
437  while (flagTable[length].name != NULL) length++;
438
439  // Sort
440  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length);
441  for (int index = 0; index < length; index++) {
442    array[index] = &flagTable[index];
443  }
444  qsort(array, length, sizeof(Flag*), compare_flags);
445
446  // Print
447  tty->print_cr("[Global flags]");
448  for (int i = 0; i < length; i++) {
449    if (array[i]->is_unlocked()) {
450      array[i]->print_on(tty);
451    }
452  }
453  FREE_C_HEAP_ARRAY(Flag*, array);
454}
455
456#endif
457