duke@435: /* kmo@4586: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #include "precompiled.hpp" stefank@2314: #include "memory/allocation.inline.hpp" stefank@2314: #include "oops/oop.inline.hpp" stefank@2314: #include "runtime/arguments.hpp" stefank@2314: #include "runtime/globals.hpp" stefank@2314: #include "runtime/globals_extension.hpp" stefank@2314: #include "utilities/ostream.hpp" jprovino@4542: #include "utilities/macros.hpp" stefank@2314: #include "utilities/top.hpp" jprovino@4542: #if INCLUDE_ALL_GCS stefank@2314: #include "gc_implementation/g1/g1_globals.hpp" jprovino@4542: #endif // INCLUDE_ALL_GCS stefank@2314: #ifdef COMPILER1 stefank@2314: #include "c1/c1_globals.hpp" stefank@2314: #endif stefank@2314: #ifdef COMPILER2 stefank@2314: #include "opto/c2_globals.hpp" stefank@2314: #endif stefank@2314: #ifdef SHARK stefank@2314: #include "shark/shark_globals.hpp" stefank@2314: #endif duke@435: duke@435: RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \ duke@435: MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \ phh@3287: MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \ phh@3287: MATERIALIZE_NOTPRODUCT_FLAG, \ coleenp@548: MATERIALIZE_MANAGEABLE_FLAG, MATERIALIZE_PRODUCT_RW_FLAG, \ coleenp@548: MATERIALIZE_LP64_PRODUCT_FLAG) duke@435: duke@435: RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \ duke@435: MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \ duke@435: MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG) duke@435: twisti@4020: ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, \ twisti@4020: MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \ twisti@4020: MATERIALIZE_NOTPRODUCT_FLAG) twisti@4020: phh@3303: MATERIALIZE_FLAGS_EXT phh@3303: phh@3303: duke@435: bool Flag::is_unlocker() const { phh@3287: return strcmp(name, "UnlockDiagnosticVMOptions") == 0 || phh@3303: strcmp(name, "UnlockExperimentalVMOptions") == 0 || phh@3303: is_unlocker_ext(); duke@435: } duke@435: duke@435: bool Flag::is_unlocked() const { kmo@4586: if (strcmp(kind, "{diagnostic}") == 0 || kmo@4586: strcmp(kind, "{C2 diagnostic}") == 0 || kmo@4586: strcmp(kind, "{ARCH diagnostic}") == 0 || kmo@4586: strcmp(kind, "{Shark diagnostic}") == 0) { duke@435: return UnlockDiagnosticVMOptions; never@1515: } else if (strcmp(kind, "{experimental}") == 0 || kmo@4586: strcmp(kind, "{C2 experimental}") == 0 || kmo@4586: strcmp(kind, "{ARCH experimental}") == 0 || kmo@4586: strcmp(kind, "{Shark experimental}") == 0) { ysr@785: return UnlockExperimentalVMOptions; duke@435: } else { phh@3303: return is_unlocked_ext(); duke@435: } duke@435: } duke@435: jmelvin@3650: // Get custom message for this locked flag, or return NULL if jmelvin@3650: // none is available. jmelvin@3650: void Flag::get_locked_message(char* buf, int buflen) const { jmelvin@3650: get_locked_message_ext(buf, buflen); jmelvin@3650: } jmelvin@3650: duke@435: bool Flag::is_writeable() const { phh@3342: return strcmp(kind, "{manageable}") == 0 || phh@3342: strcmp(kind, "{product rw}") == 0 || phh@3342: is_writeable_ext(); duke@435: } duke@435: phh@3342: // All flags except "manageable" are assumed to be internal flags. duke@435: // Long term, we need to define a mechanism to specify which flags duke@435: // are external/stable and change this function accordingly. duke@435: bool Flag::is_external() const { phh@3342: return strcmp(kind, "{manageable}") == 0 || is_external_ext(); duke@435: } duke@435: phh@3342: duke@435: // Length of format string (e.g. "%.1234s") for printing ccstr below duke@435: #define FORMAT_BUFFER_LEN 16 duke@435: ikrylov@2123: void Flag::print_on(outputStream* st, bool withComments) { ikrylov@2123: st->print("%9s %-40s %c= ", type, name, (origin != DEFAULT ? ':' : ' ')); phh@1502: if (is_bool()) st->print("%-16s", get_bool() ? "true" : "false"); phh@1502: if (is_intx()) st->print("%-16ld", get_intx()); phh@1502: if (is_uintx()) st->print("%-16lu", get_uintx()); phh@1502: if (is_uint64_t()) st->print("%-16lu", get_uint64_t()); ikrylov@2123: if (is_double()) st->print("%-16f", get_double()); ikrylov@2123: duke@435: if (is_ccstr()) { ikrylov@2123: const char* cp = get_ccstr(); ikrylov@2123: if (cp != NULL) { ikrylov@2123: const char* eol; ikrylov@2123: while ((eol = strchr(cp, '\n')) != NULL) { ikrylov@2123: char format_buffer[FORMAT_BUFFER_LEN]; ikrylov@2123: size_t llen = pointer_delta(eol, cp, sizeof(char)); ikrylov@2123: jio_snprintf(format_buffer, FORMAT_BUFFER_LEN, never@538: "%%." SIZE_FORMAT "s", llen); ikrylov@2123: st->print(format_buffer, cp); ikrylov@2123: st->cr(); ikrylov@2123: cp = eol+1; ikrylov@2123: st->print("%5s %-35s += ", "", name); ikrylov@2123: } ikrylov@2123: st->print("%-16s", cp); ikrylov@2123: } ikrylov@2123: else st->print("%-16s", ""); duke@435: } ikrylov@2123: st->print("%-20s", kind); ikrylov@2123: if (withComments) { ikrylov@2123: #ifndef PRODUCT ikrylov@2123: st->print("%s", doc ); ikrylov@2123: #endif ikrylov@2123: } duke@435: st->cr(); duke@435: } duke@435: duke@435: void Flag::print_as_flag(outputStream* st) { duke@435: if (is_bool()) { duke@435: st->print("-XX:%s%s", get_bool() ? "+" : "-", name); duke@435: } else if (is_intx()) { duke@435: st->print("-XX:%s=" INTX_FORMAT, name, get_intx()); duke@435: } else if (is_uintx()) { duke@435: st->print("-XX:%s=" UINTX_FORMAT, name, get_uintx()); phh@1502: } else if (is_uint64_t()) { phh@1502: st->print("-XX:%s=" UINT64_FORMAT, name, get_uint64_t()); brutisso@3752: } else if (is_double()) { brutisso@3752: st->print("-XX:%s=%f", name, get_double()); duke@435: } else if (is_ccstr()) { duke@435: st->print("-XX:%s=", name); never@538: const char* cp = get_ccstr(); never@538: if (cp != NULL) { never@538: // Need to turn embedded '\n's back into separate arguments never@538: // Not so efficient to print one character at a time, never@538: // but the choice is to do the transformation to a buffer never@538: // and print that. And this need not be efficient. never@538: for (; *cp != '\0'; cp += 1) { never@538: switch (*cp) { never@538: default: never@538: st->print("%c", *cp); never@538: break; never@538: case '\n': never@538: st->print(" -XX:%s=", name); never@538: break; never@538: } duke@435: } duke@435: } duke@435: } else { duke@435: ShouldNotReachHere(); duke@435: } duke@435: } duke@435: duke@435: // 4991491 do not "optimize out" the was_set false values: omitting them duke@435: // tickles a Microsoft compiler bug causing flagTable to be malformed duke@435: ikrylov@2123: #define RUNTIME_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product}", DEFAULT }, ikrylov@2123: #define RUNTIME_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{pd product}", DEFAULT }, ikrylov@2123: #define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{diagnostic}", DEFAULT }, ikrylov@2123: #define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{experimental}", DEFAULT }, ikrylov@2123: #define RUNTIME_MANAGEABLE_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{manageable}", DEFAULT }, ikrylov@2123: #define RUNTIME_PRODUCT_RW_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product rw}", DEFAULT }, duke@435: duke@435: #ifdef PRODUCT duke@435: #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ duke@435: #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ duke@435: #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) duke@435: #else ikrylov@2123: #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "", DEFAULT }, ikrylov@2123: #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{pd}", DEFAULT }, ikrylov@2123: #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{notproduct}", DEFAULT }, duke@435: #endif duke@435: coleenp@548: #ifdef _LP64 ikrylov@2123: #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{lp64_product}", DEFAULT }, coleenp@548: #else coleenp@548: #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ coleenp@548: #endif // _LP64 coleenp@548: ikrylov@2123: #define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 product}", DEFAULT }, ikrylov@2123: #define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 pd product}", DEFAULT }, duke@435: #ifdef PRODUCT duke@435: #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ duke@435: #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ duke@435: #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) duke@435: #else ikrylov@2123: #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1}", DEFAULT }, ikrylov@2123: #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{C1 pd}", DEFAULT }, ikrylov@2123: #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1 notproduct}", DEFAULT }, duke@435: #endif duke@435: ikrylov@2123: #define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 product}", DEFAULT }, ikrylov@2123: #define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 pd product}", DEFAULT }, ikrylov@2123: #define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 diagnostic}", DEFAULT }, ikrylov@2123: #define C2_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 experimental}", DEFAULT }, duke@435: #ifdef PRODUCT duke@435: #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ duke@435: #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ duke@435: #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) duke@435: #else ikrylov@2123: #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2}", DEFAULT }, ikrylov@2123: #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{C2 pd}", DEFAULT }, ikrylov@2123: #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2 notproduct}", DEFAULT }, duke@435: #endif duke@435: twisti@4020: #define ARCH_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH product}", DEFAULT }, twisti@4020: #define ARCH_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH diagnostic}", DEFAULT }, twisti@4020: #define ARCH_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH experimental}", DEFAULT }, twisti@4020: #ifdef PRODUCT twisti@4020: #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ twisti@4020: #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) twisti@4020: #else twisti@4020: #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH}", DEFAULT }, twisti@4020: #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH notproduct}", DEFAULT }, twisti@4020: #endif twisti@4020: ikrylov@2123: #define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark product}", DEFAULT }, ikrylov@2123: #define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark pd product}", DEFAULT }, ikrylov@2123: #define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark diagnostic}", DEFAULT }, twisti@2047: #ifdef PRODUCT twisti@2047: #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ twisti@2047: #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ twisti@2047: #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) twisti@2047: #else ikrylov@2123: #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark}", DEFAULT }, ikrylov@2123: #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{Shark pd}", DEFAULT }, ikrylov@2123: #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark notproduct}", DEFAULT }, twisti@2047: #endif duke@435: duke@435: static Flag flagTable[] = { phh@3287: 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_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT) duke@435: 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) jprovino@4542: #if INCLUDE_ALL_GCS ysr@785: 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_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT) jprovino@4542: #endif // INCLUDE_ALL_GCS duke@435: #ifdef COMPILER1 duke@435: C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT) duke@435: #endif duke@435: #ifdef COMPILER2 never@1515: 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_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT) duke@435: #endif twisti@2047: #ifdef SHARK twisti@2047: SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, SHARK_PD_DEVELOP_FLAG_STRUCT, SHARK_PRODUCT_FLAG_STRUCT, SHARK_PD_PRODUCT_FLAG_STRUCT, SHARK_DIAGNOSTIC_FLAG_STRUCT, SHARK_NOTPRODUCT_FLAG_STRUCT) twisti@2047: #endif twisti@4020: ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, ARCH_PRODUCT_FLAG_STRUCT, ARCH_DIAGNOSTIC_FLAG_STRUCT, ARCH_EXPERIMENTAL_FLAG_STRUCT, ARCH_NOTPRODUCT_FLAG_STRUCT) phh@3303: FLAGTABLE_EXT duke@435: {0, NULL, NULL} duke@435: }; duke@435: duke@435: Flag* Flag::flags = flagTable; duke@435: size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag)); duke@435: tamao@5343: inline bool str_equal(const char* s, const char* q, size_t len) { duke@435: // s is null terminated, q is not! duke@435: if (strlen(s) != (unsigned int) len) return false; duke@435: return strncmp(s, q, len) == 0; duke@435: } duke@435: jmelvin@3650: // Search the flag table for a named flag tamao@5343: Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked) { jmelvin@3650: for (Flag* current = &flagTable[0]; current->name != NULL; current++) { duke@435: if (str_equal(current->name, name, length)) { jmelvin@3650: // Found a matching entry. Report locked flags only if allowed. duke@435: if (!(current->is_unlocked() || current->is_unlocker())) { jmelvin@3650: if (!allow_locked) { jmelvin@3650: // disable use of locked flags, e.g. diagnostic, experimental, jmelvin@3650: // commercial... until they are explicitly unlocked jmelvin@3650: return NULL; jmelvin@3650: } duke@435: } duke@435: return current; duke@435: } duke@435: } jmelvin@3650: // Flag name is not in the flag table duke@435: return NULL; duke@435: } duke@435: tamao@5343: // Compute string similarity based on Dice's coefficient tamao@5343: static float str_similar(const char* str1, const char* str2, size_t len2) { tamao@5343: int len1 = (int) strlen(str1); tamao@5343: int total = len1 + (int) len2; tamao@5343: tamao@5343: int hit = 0; tamao@5343: tamao@5343: for (int i = 0; i < len1 -1; ++i) { tamao@5343: for (int j = 0; j < (int) len2 -1; ++j) { tamao@5343: if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) { tamao@5343: ++hit; tamao@5343: break; tamao@5343: } tamao@5343: } tamao@5343: } tamao@5343: tamao@5343: return 2.0f * (float) hit / (float) total; tamao@5343: } tamao@5343: tamao@5343: Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) { tamao@5343: float VMOptionsFuzzyMatchSimilarity = 0.7f; tamao@5343: Flag* match = NULL; tamao@5343: float score; tamao@5343: float max_score = -1; tamao@5343: tamao@5343: for (Flag* current = &flagTable[0]; current->name != NULL; current++) { tamao@5343: score = str_similar(current->name, name, length); tamao@5343: if (score > max_score) { tamao@5343: max_score = score; tamao@5343: match = current; tamao@5343: } tamao@5343: } tamao@5343: tamao@5343: if (!(match->is_unlocked() || match->is_unlocker())) { tamao@5343: if (!allow_locked) { tamao@5343: return NULL; tamao@5343: } tamao@5343: } tamao@5343: tamao@5343: if (max_score < VMOptionsFuzzyMatchSimilarity) { tamao@5343: return NULL; tamao@5343: } tamao@5343: tamao@5343: return match; tamao@5343: } tamao@5343: duke@435: // Returns the address of the index'th element duke@435: static Flag* address_of_flag(CommandLineFlagWithType flag) { duke@435: assert((size_t)flag < Flag::numFlags, "bad command line flag index"); duke@435: return &Flag::flags[flag]; duke@435: } duke@435: duke@435: bool CommandLineFlagsEx::is_default(CommandLineFlag flag) { duke@435: assert((size_t)flag < Flag::numFlags, "bad command line flag index"); duke@435: Flag* f = &Flag::flags[flag]; duke@435: return (f->origin == DEFAULT); duke@435: } duke@435: jmasa@448: bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) { jmasa@448: assert((size_t)flag < Flag::numFlags, "bad command line flag index"); jmasa@448: Flag* f = &Flag::flags[flag]; jmasa@448: return (f->origin == ERGONOMIC); jmasa@448: } jmasa@448: jmasa@448: bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) { jmasa@448: assert((size_t)flag < Flag::numFlags, "bad command line flag index"); jmasa@448: Flag* f = &Flag::flags[flag]; jmasa@448: return (f->origin == COMMAND_LINE); jmasa@448: } jmasa@448: duke@435: bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) { duke@435: Flag* result = Flag::find_flag((char*)name, strlen(name)); duke@435: if (result == NULL) return false; duke@435: *value = (result->origin == COMMAND_LINE); duke@435: return true; duke@435: } duke@435: duke@435: bool CommandLineFlags::boolAt(char* name, size_t len, bool* value) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_bool()) return false; duke@435: *value = result->get_bool(); duke@435: return true; duke@435: } duke@435: duke@435: bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_bool()) return false; duke@435: bool old_value = result->get_bool(); duke@435: result->set_bool(*value); duke@435: *value = old_value; duke@435: result->origin = origin; duke@435: return true; duke@435: } duke@435: duke@435: void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin) { duke@435: Flag* faddr = address_of_flag(flag); duke@435: guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type"); duke@435: faddr->set_bool(value); duke@435: faddr->origin = origin; duke@435: } duke@435: duke@435: bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_intx()) return false; duke@435: *value = result->get_intx(); duke@435: return true; duke@435: } duke@435: duke@435: bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_intx()) return false; duke@435: intx old_value = result->get_intx(); duke@435: result->set_intx(*value); duke@435: *value = old_value; duke@435: result->origin = origin; duke@435: return true; duke@435: } duke@435: duke@435: void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin) { duke@435: Flag* faddr = address_of_flag(flag); duke@435: guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type"); duke@435: faddr->set_intx(value); duke@435: faddr->origin = origin; duke@435: } duke@435: duke@435: bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_uintx()) return false; duke@435: *value = result->get_uintx(); duke@435: return true; duke@435: } duke@435: duke@435: bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_uintx()) return false; duke@435: uintx old_value = result->get_uintx(); duke@435: result->set_uintx(*value); duke@435: *value = old_value; duke@435: result->origin = origin; duke@435: return true; duke@435: } duke@435: duke@435: void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin) { duke@435: Flag* faddr = address_of_flag(flag); duke@435: guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type"); duke@435: faddr->set_uintx(value); duke@435: faddr->origin = origin; duke@435: } duke@435: phh@1499: bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) { phh@1499: Flag* result = Flag::find_flag(name, len); phh@1499: if (result == NULL) return false; phh@1499: if (!result->is_uint64_t()) return false; phh@1499: *value = result->get_uint64_t(); phh@1499: return true; phh@1499: } phh@1499: phh@1499: bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin) { phh@1499: Flag* result = Flag::find_flag(name, len); phh@1499: if (result == NULL) return false; phh@1499: if (!result->is_uint64_t()) return false; phh@1499: uint64_t old_value = result->get_uint64_t(); phh@1499: result->set_uint64_t(*value); phh@1499: *value = old_value; phh@1499: result->origin = origin; phh@1499: return true; phh@1499: } phh@1499: phh@1499: void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin) { phh@1499: Flag* faddr = address_of_flag(flag); phh@1499: guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type"); phh@1499: faddr->set_uint64_t(value); phh@1499: faddr->origin = origin; phh@1499: } phh@1499: duke@435: bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_double()) return false; duke@435: *value = result->get_double(); duke@435: return true; duke@435: } duke@435: duke@435: bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_double()) return false; duke@435: double old_value = result->get_double(); duke@435: result->set_double(*value); duke@435: *value = old_value; duke@435: result->origin = origin; duke@435: return true; duke@435: } duke@435: duke@435: void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin) { duke@435: Flag* faddr = address_of_flag(flag); duke@435: guarantee(faddr != NULL && faddr->is_double(), "wrong flag type"); duke@435: faddr->set_double(value); duke@435: faddr->origin = origin; duke@435: } duke@435: duke@435: bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_ccstr()) return false; duke@435: *value = result->get_ccstr(); duke@435: return true; duke@435: } duke@435: duke@435: // Contract: Flag will make private copy of the incoming value. duke@435: // Outgoing value is always malloc-ed, and caller MUST call free. duke@435: bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin) { duke@435: Flag* result = Flag::find_flag(name, len); duke@435: if (result == NULL) return false; duke@435: if (!result->is_ccstr()) return false; duke@435: ccstr old_value = result->get_ccstr(); never@805: char* new_value = NULL; never@805: if (*value != NULL) { zgu@3900: new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1, mtInternal); never@805: strcpy(new_value, *value); never@805: } duke@435: result->set_ccstr(new_value); duke@435: if (result->origin == DEFAULT && old_value != NULL) { duke@435: // Prior value is NOT heap allocated, but was a literal constant. zgu@3900: char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal); duke@435: strcpy(old_value_to_free, old_value); duke@435: old_value = old_value_to_free; duke@435: } duke@435: *value = old_value; duke@435: result->origin = origin; duke@435: return true; duke@435: } duke@435: duke@435: // Contract: Flag will make private copy of the incoming value. duke@435: void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin) { duke@435: Flag* faddr = address_of_flag(flag); duke@435: guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type"); duke@435: ccstr old_value = faddr->get_ccstr(); zgu@3900: char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal); duke@435: strcpy(new_value, value); duke@435: faddr->set_ccstr(new_value); duke@435: if (faddr->origin != DEFAULT && old_value != NULL) { duke@435: // Prior value is heap allocated so free it. zgu@3900: FREE_C_HEAP_ARRAY(char, old_value, mtInternal); duke@435: } duke@435: faddr->origin = origin; duke@435: } duke@435: duke@435: extern "C" { duke@435: static int compare_flags(const void* void_a, const void* void_b) { duke@435: return strcmp((*((Flag**) void_a))->name, (*((Flag**) void_b))->name); duke@435: } duke@435: } duke@435: fparain@3402: void CommandLineFlags::printSetFlags(outputStream* out) { duke@435: // Print which flags were set on the command line duke@435: // note: this method is called before the thread structure is in place duke@435: // which means resource allocation cannot be used. duke@435: duke@435: // Compute size duke@435: int length= 0; duke@435: while (flagTable[length].name != NULL) length++; duke@435: duke@435: // Sort zgu@3900: Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal); duke@435: for (int index = 0; index < length; index++) { duke@435: array[index] = &flagTable[index]; duke@435: } duke@435: qsort(array, length, sizeof(Flag*), compare_flags); duke@435: duke@435: // Print duke@435: for (int i = 0; i < length; i++) { duke@435: if (array[i]->origin /* naked field! */) { fparain@3402: array[i]->print_as_flag(out); fparain@3402: out->print(" "); duke@435: } duke@435: } fparain@3402: out->cr(); zgu@3900: FREE_C_HEAP_ARRAY(Flag*, array, mtInternal); duke@435: } duke@435: duke@435: #ifndef PRODUCT duke@435: duke@435: duke@435: void CommandLineFlags::verify() { duke@435: assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict"); duke@435: } duke@435: kvn@1585: #endif // PRODUCT kvn@1585: fparain@3402: void CommandLineFlags::printFlags(outputStream* out, bool withComments) { duke@435: // Print the flags sorted by name duke@435: // note: this method is called before the thread structure is in place duke@435: // which means resource allocation cannot be used. duke@435: duke@435: // Compute size duke@435: int length= 0; duke@435: while (flagTable[length].name != NULL) length++; duke@435: duke@435: // Sort zgu@3900: Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal); duke@435: for (int index = 0; index < length; index++) { duke@435: array[index] = &flagTable[index]; duke@435: } duke@435: qsort(array, length, sizeof(Flag*), compare_flags); duke@435: duke@435: // Print fparain@3402: out->print_cr("[Global flags]"); duke@435: for (int i = 0; i < length; i++) { duke@435: if (array[i]->is_unlocked()) { fparain@3402: array[i]->print_on(out, withComments); duke@435: } duke@435: } zgu@3900: FREE_C_HEAP_ARRAY(Flag*, array, mtInternal); duke@435: }