331 }
332 get_locked_message_ext(buf, buflen);
333 }
334
335 bool Flag::is_writeable() const {
336 return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
337 }
338
339 // All flags except "manageable" are assumed to be internal flags.
340 // Long term, we need to define a mechanism to specify which flags
341 // are external/stable and change this function accordingly.
342 bool Flag::is_external() const {
343 return is_manageable() || is_external_ext();
344 }
345
346
347 // Length of format string (e.g. "%.1234s") for printing ccstr below
348 #define FORMAT_BUFFER_LEN 16
349
350 PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
351 void Flag::print_on(outputStream* st, bool printRanges, bool withComments) {
352 // Don't print notproduct and develop flags in a product build.
353 if (is_constant_in_binary()) {
354 return;
355 }
356
357 if (!printRanges) {
358
359 st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
360
361 if (is_bool()) {
362 st->print("%-16s", get_bool() ? "true" : "false");
363 } else if (is_int()) {
364 st->print("%-16d", get_int());
365 } else if (is_uint()) {
366 st->print("%-16u", get_uint());
367 } else if (is_intx()) {
368 st->print("%-16ld", get_intx());
369 } else if (is_uintx()) {
370 st->print("%-16lu", get_uintx());
371 } else if (is_uint64_t()) {
637 FLAGTABLE_EXT
638 {0, NULL, NULL}
639 };
640
641 Flag* Flag::flags = flagTable;
642 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
643
644 inline bool str_equal(const char* s, const char* q, size_t len) {
645 // s is null terminated, q is not!
646 if (strlen(s) != (unsigned int) len) return false;
647 return strncmp(s, q, len) == 0;
648 }
649
650 // Search the flag table for a named flag
651 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
652 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
653 if (str_equal(current->_name, name, length)) {
654 // Found a matching entry.
655 // Don't report notproduct and develop flags in product builds.
656 if (current->is_constant_in_binary()) {
657 return (return_flag == true ? current : NULL);
658 }
659 // Report locked flags only if allowed.
660 if (!(current->is_unlocked() || current->is_unlocker())) {
661 if (!allow_locked) {
662 // disable use of locked flags, e.g. diagnostic, experimental,
663 // commercial... until they are explicitly unlocked
664 return NULL;
665 }
666 }
667 return current;
668 }
669 }
670 // Flag name is not in the flag table
671 return NULL;
672 }
673
674 // Compute string similarity based on Dice's coefficient
675 static float str_similar(const char* str1, const char* str2, size_t len2) {
676 int len1 = (int) strlen(str1);
677 int total = len1 + (int) len2;
741 return f->is_command_line();
742 }
743
744 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
745 Flag* result = Flag::find_flag((char*)name, strlen(name));
746 if (result == NULL) return false;
747 *value = result->is_command_line();
748 return true;
749 }
750
751 template<class E, class T>
752 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) {
753 E e;
754 e.set_name(name);
755 e.set_old_value(old_value);
756 e.set_new_value(new_value);
757 e.set_origin(origin);
758 e.commit();
759 }
760
761 static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool* new_value, bool verbose = true) {
762 Flag::Error status = Flag::SUCCESS;
763 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
764 if (constraint != NULL) {
765 status = constraint->apply_bool(new_value, verbose);
766 }
767 return status;
768 }
769
770 Flag::Error CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) {
771 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
772 if (result == NULL) return Flag::INVALID_FLAG;
773 if (!result->is_bool()) return Flag::WRONG_FORMAT;
774 *value = result->get_bool();
775 return Flag::SUCCESS;
776 }
777
778 Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
779 Flag* result = Flag::find_flag(name, len);
780 if (result == NULL) return Flag::INVALID_FLAG;
784 bool old_value = result->get_bool();
785 trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
786 result->set_bool(*value);
787 *value = old_value;
788 result->set_origin(origin);
789 return Flag::SUCCESS;
790 }
791
792 Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
793 Flag* faddr = address_of_flag(flag);
794 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
795 Flag::Error check = apply_constraint_and_check_range_bool(faddr->_name, &value);
796 if (check != Flag::SUCCESS) return check;
797 trace_flag_changed<EventBooleanFlagChanged, bool>(faddr->_name, faddr->get_bool(), value, origin);
798 faddr->set_bool(value);
799 faddr->set_origin(origin);
800 return Flag::SUCCESS;
801 }
802
803 static Flag::Error apply_constraint_and_check_range_int(const char* name, int* new_value, bool verbose = true) {
804 Flag::Error status = Flag::SUCCESS;
805 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
806 if (range != NULL) {
807 status = range->check_int(*new_value, verbose);
808 }
809 if (status == Flag::SUCCESS) {
810 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
811 if (constraint != NULL) {
812 status = constraint->apply_int(new_value, verbose);
813 }
814 }
815 return status;
816 }
817
818 Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
819 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
820 if (result == NULL) return Flag::INVALID_FLAG;
821 if (!result->is_int()) return Flag::WRONG_FORMAT;
822 *value = result->get_int();
823 return Flag::SUCCESS;
824 }
825
826 Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
827 Flag* result = Flag::find_flag(name, len);
828 if (result == NULL) return Flag::INVALID_FLAG;
829 if (!result->is_int()) return Flag::WRONG_FORMAT;
830 Flag::Error check = apply_constraint_and_check_range_int(name, value, !CommandLineFlags::finishedInitializing());
831 if (check != Flag::SUCCESS) return check;
832 int old_value = result->get_int();
833 trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
834 result->set_int(*value);
835 *value = old_value;
836 result->set_origin(origin);
837 return Flag::SUCCESS;
838 }
839
840 Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
841 Flag* faddr = address_of_flag(flag);
842 guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
843 trace_flag_changed<EventIntFlagChanged, s4>(faddr->_name, faddr->get_int(), value, origin);
844 faddr->set_int(value);
845 faddr->set_origin(origin);
846 return Flag::SUCCESS;
847 }
848
849 static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint* new_value, bool verbose = true) {
850 Flag::Error status = Flag::SUCCESS;
851 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
852 if (range != NULL) {
853 status = range->check_uint(*new_value, verbose);
854 }
855 if (status == Flag::SUCCESS) {
856 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
857 if (constraint != NULL) {
858 status = constraint->apply_uint(new_value, verbose);
859 }
860 }
861 return status;
862 }
863
864 Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
865 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
866 if (result == NULL) return Flag::INVALID_FLAG;
867 if (!result->is_uint()) return Flag::WRONG_FORMAT;
868 *value = result->get_uint();
869 return Flag::SUCCESS;
870 }
871
872 Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
873 Flag* result = Flag::find_flag(name, len);
874 if (result == NULL) return Flag::INVALID_FLAG;
875 if (!result->is_uint()) return Flag::WRONG_FORMAT;
876 Flag::Error check = apply_constraint_and_check_range_uint(name, value, !CommandLineFlags::finishedInitializing());
877 if (check != Flag::SUCCESS) return check;
878 uint old_value = result->get_uint();
879 trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
880 result->set_uint(*value);
881 *value = old_value;
884 }
885
886 Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
887 Flag* faddr = address_of_flag(flag);
888 guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
889 trace_flag_changed<EventUnsignedIntFlagChanged, u4>(faddr->_name, faddr->get_uint(), value, origin);
890 faddr->set_uint(value);
891 faddr->set_origin(origin);
892 return Flag::SUCCESS;
893 }
894
895 Flag::Error CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
896 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
897 if (result == NULL) return Flag::INVALID_FLAG;
898 if (!result->is_intx()) return Flag::WRONG_FORMAT;
899 *value = result->get_intx();
900 return Flag::SUCCESS;
901 }
902
903 static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx* new_value, bool verbose = true) {
904 Flag::Error status = Flag::SUCCESS;
905 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
906 if (range != NULL) {
907 status = range->check_intx(*new_value, verbose);
908 }
909 if (status == Flag::SUCCESS) {
910 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
911 if (constraint != NULL) {
912 status = constraint->apply_intx(new_value, verbose);
913 }
914 }
915 return status;
916 }
917
918 Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
919 Flag* result = Flag::find_flag(name, len);
920 if (result == NULL) return Flag::INVALID_FLAG;
921 if (!result->is_intx()) return Flag::WRONG_FORMAT;
922 Flag::Error check = apply_constraint_and_check_range_intx(name, value, !CommandLineFlags::finishedInitializing());
923 if (check != Flag::SUCCESS) return check;
924 intx old_value = result->get_intx();
925 trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
926 result->set_intx(*value);
927 *value = old_value;
928 result->set_origin(origin);
929 return Flag::SUCCESS;
930 }
931
932 Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
933 Flag* faddr = address_of_flag(flag);
934 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
935 Flag::Error check = apply_constraint_and_check_range_intx(faddr->_name, &value);
936 if (check != Flag::SUCCESS) return check;
937 trace_flag_changed<EventLongFlagChanged, intx>(faddr->_name, faddr->get_intx(), value, origin);
938 faddr->set_intx(value);
939 faddr->set_origin(origin);
940 return Flag::SUCCESS;
941 }
942
943 Flag::Error CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
944 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
945 if (result == NULL) return Flag::INVALID_FLAG;
946 if (!result->is_uintx()) return Flag::WRONG_FORMAT;
947 *value = result->get_uintx();
948 return Flag::SUCCESS;
949 }
950
951 static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx* new_value, bool verbose = true) {
952 Flag::Error status = Flag::SUCCESS;
953 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
954 if (range != NULL) {
955 status = range->check_uintx(*new_value, verbose);
956 }
957 if (status == Flag::SUCCESS) {
958 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
959 if (constraint != NULL) {
960 status = constraint->apply_uintx(new_value, verbose);
961 }
962 }
963 return status;
964 }
965
966 Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
967 Flag* result = Flag::find_flag(name, len);
968 if (result == NULL) return Flag::INVALID_FLAG;
969 if (!result->is_uintx()) return Flag::WRONG_FORMAT;
970 Flag::Error check = apply_constraint_and_check_range_uintx(name, value, !CommandLineFlags::finishedInitializing());
971 if (check != Flag::SUCCESS) return check;
972 uintx old_value = result->get_uintx();
973 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
974 result->set_uintx(*value);
975 *value = old_value;
976 result->set_origin(origin);
977 return Flag::SUCCESS;
978 }
979
980 Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
981 Flag* faddr = address_of_flag(flag);
982 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
983 Flag::Error check = apply_constraint_and_check_range_uintx(faddr->_name, &value);
984 if (check != Flag::SUCCESS) return check;
985 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uintx(), value, origin);
986 faddr->set_uintx(value);
987 faddr->set_origin(origin);
988 return Flag::SUCCESS;
989 }
990
991 Flag::Error CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
992 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
993 if (result == NULL) return Flag::INVALID_FLAG;
994 if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
995 *value = result->get_uint64_t();
996 return Flag::SUCCESS;
997 }
998
999 static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t* new_value, bool verbose = true) {
1000 Flag::Error status = Flag::SUCCESS;
1001 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1002 if (range != NULL) {
1003 status = range->check_uint64_t(*new_value, verbose);
1004 }
1005 if (status == Flag::SUCCESS) {
1006 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
1007 if (constraint != NULL) {
1008 status = constraint->apply_uint64_t(new_value, verbose);
1009 }
1010 }
1011 return status;
1012 }
1013
1014 Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
1015 Flag* result = Flag::find_flag(name, len);
1016 if (result == NULL) return Flag::INVALID_FLAG;
1017 if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
1018 Flag::Error check = apply_constraint_and_check_range_uint64_t(name, value, !CommandLineFlags::finishedInitializing());
1019 if (check != Flag::SUCCESS) return check;
1020 uint64_t old_value = result->get_uint64_t();
1021 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1022 result->set_uint64_t(*value);
1023 *value = old_value;
1024 result->set_origin(origin);
1025 return Flag::SUCCESS;
1026 }
1027
1028 Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
1029 Flag* faddr = address_of_flag(flag);
1030 guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
1031 Flag::Error check = apply_constraint_and_check_range_uint64_t(faddr->_name, &value);
1032 if (check != Flag::SUCCESS) return check;
1033 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uint64_t(), value, origin);
1034 faddr->set_uint64_t(value);
1035 faddr->set_origin(origin);
1036 return Flag::SUCCESS;
1037 }
1038
1039 Flag::Error CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
1040 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1041 if (result == NULL) return Flag::INVALID_FLAG;
1042 if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1043 *value = result->get_size_t();
1044 return Flag::SUCCESS;
1045 }
1046
1047 static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t* new_value, bool verbose = true) {
1048 Flag::Error status = Flag::SUCCESS;
1049 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1050 if (range != NULL) {
1051 status = range->check_size_t(*new_value, verbose);
1052 }
1053 if (status == Flag::SUCCESS) {
1054 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
1055 if (constraint != NULL) {
1056 status = constraint->apply_size_t(new_value, verbose);
1057 }
1058 }
1059 return status;
1060 }
1061
1062 Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
1063 Flag* result = Flag::find_flag(name, len);
1064 if (result == NULL) return Flag::INVALID_FLAG;
1065 if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1066 Flag::Error check = apply_constraint_and_check_range_size_t(name, value, !CommandLineFlags::finishedInitializing());
1067 if (check != Flag::SUCCESS) return check;
1068 size_t old_value = result->get_size_t();
1069 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1070 result->set_size_t(*value);
1071 *value = old_value;
1072 result->set_origin(origin);
1073 return Flag::SUCCESS;
1074 }
1075
1076 Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
1077 Flag* faddr = address_of_flag(flag);
1078 guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
1079 Flag::Error check = apply_constraint_and_check_range_size_t(faddr->_name, &value);
1080 if (check != Flag::SUCCESS) return check;
1081 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_size_t(), value, origin);
1082 faddr->set_size_t(value);
1083 faddr->set_origin(origin);
1084 return Flag::SUCCESS;
1085 }
1086
1087 Flag::Error CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
1088 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1089 if (result == NULL) return Flag::INVALID_FLAG;
1090 if (!result->is_double()) return Flag::WRONG_FORMAT;
1091 *value = result->get_double();
1092 return Flag::SUCCESS;
1093 }
1094
1095 static Flag::Error apply_constraint_and_check_range_double(const char* name, double* new_value, bool verbose = true) {
1096 Flag::Error status = Flag::SUCCESS;
1097 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1098 if (range != NULL) {
1099 status = range->check_double(*new_value, verbose);
1100 }
1101 if (status == Flag::SUCCESS) {
1102 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
1103 if (constraint != NULL) {
1104 status = constraint->apply_double(new_value, verbose);
1105 }
1106 }
1107 return status;
1108 }
1109
1110 Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
1111 Flag* result = Flag::find_flag(name, len);
1112 if (result == NULL) return Flag::INVALID_FLAG;
1113 if (!result->is_double()) return Flag::WRONG_FORMAT;
1114 Flag::Error check = apply_constraint_and_check_range_double(name, value, !CommandLineFlags::finishedInitializing());
1115 if (check != Flag::SUCCESS) return check;
1116 double old_value = result->get_double();
1117 trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
1118 result->set_double(*value);
1119 *value = old_value;
1120 result->set_origin(origin);
1121 return Flag::SUCCESS;
1122 }
1123
1124 Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
1125 Flag* faddr = address_of_flag(flag);
1126 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
1127 Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, &value, !CommandLineFlags::finishedInitializing());
1158 *value = old_value;
1159 result->set_origin(origin);
1160 return Flag::SUCCESS;
1161 }
1162
1163 Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
1164 Flag* faddr = address_of_flag(flag);
1165 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
1166 ccstr old_value = faddr->get_ccstr();
1167 trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
1168 char* new_value = os::strdup_check_oom(value);
1169 faddr->set_ccstr(new_value);
1170 if (!faddr->is_default() && old_value != NULL) {
1171 // Prior value is heap allocated so free it.
1172 FREE_C_HEAP_ARRAY(char, old_value);
1173 }
1174 faddr->set_origin(origin);
1175 return Flag::SUCCESS;
1176 }
1177
1178 //#define PRINT_FLAGS_SORTED_BY_TYPE_THEN_NAMES
1179 #ifndef PRINT_FLAGS_SORTED_BY_TYPE_THEN_NAMES
1180
1181 extern "C" {
1182 static int compare_flags(const void* void_a, const void* void_b) {
1183 return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
1184 }
1185 }
1186
1187 #else // PRINT_FLAGS_SORTED_BY_TYPE_THEN_NAMES
1188
1189 void print_kind(Flag::Flags flags, char* string, int size) {
1190 struct Data {
1191 int flag;
1192 const char* name;
1193 };
1194
1195 Data data[] = {
1196 { Flag::KIND_C1, "C1" },
1197 { Flag::KIND_C2, "C2" },
1198 { Flag::KIND_ARCH, "ARCH" },
1199 { Flag::KIND_SHARK, "SHARK" },
1200 { Flag::KIND_PLATFORM_DEPENDENT, "pd" },
1201 { Flag::KIND_PRODUCT, "product" },
1202 { Flag::KIND_MANAGEABLE, "manageable" },
1203 { Flag::KIND_DIAGNOSTIC, "diagnostic" },
1204 { Flag::KIND_EXPERIMENTAL, "experimental" },
1205 { Flag::KIND_COMMERCIAL, "commercial" },
1206 { Flag::KIND_NOT_PRODUCT, "notproduct" },
1207 { Flag::KIND_DEVELOP, "develop" },
1208 { Flag::KIND_LP64_PRODUCT, "lp64_product" },
1209 { Flag::KIND_READ_WRITE, "rw" },
1210 { -1, "" }
1211 };
1212
1213 if ((flags & Flag::KIND_MASK) != 0) {
1214 strncpy(string, "{", size);
1215 bool is_first = true;
1216
1217 for (int i = 0; data[i].flag != -1; i++) {
1218 Data d = data[i];
1219 if ((flags & d.flag) != 0) {
1220 if (is_first) {
1221 is_first = false;
1222 } else {
1223 os::strlcat(string, " ", size);
1224 }
1225 os::strlcat(string, d.name, size);
1226 }
1227 }
1228
1229 os::strlcat(string, "}", size);
1230 }
1231 }
1232
1233 extern "C" {
1234 // by kind, name
1235 static int compare_flags(const void* void_a, const void* void_b) {
1236 char buf_a[128];
1237 print_kind((*((Flag**) void_a))->_flags, &buf_a[0], 127);
1238 char buf_b[128];
1239 print_kind((*((Flag**) void_b))->_flags, &buf_b[0], 127);
1240 int comp_kind = strncmp(buf_a, buf_b, 127);
1241 if (comp_kind != 0) {
1242 return comp_kind;
1243 } else {
1244 return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
1245 }
1246 }
1247 }
1248
1249 #endif //PRINT_FLAGS_SORTED_BY_TYPE_THEN_NAMES
1250
1251 void CommandLineFlags::printSetFlags(outputStream* out) {
1252 // Print which flags were set on the command line
1253 // note: this method is called before the thread structure is in place
1254 // which means resource allocation cannot be used.
1255
1256 // The last entry is the null entry.
1257 const size_t length = Flag::numFlags - 1;
1258
1259 // Sort
1260 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1261 for (size_t i = 0; i < length; i++) {
1262 array[i] = &flagTable[i];
1263 }
1264 qsort(array, length, sizeof(Flag*), compare_flags);
1265
1266 // Print
1267 for (size_t i = 0; i < length; i++) {
1268 if (array[i]->get_origin() /* naked field! */) {
1269 array[i]->print_as_flag(out);
1270 out->print(" ");
1271 }
1272 }
1273 out->cr();
1274 FREE_C_HEAP_ARRAY(Flag*, array);
1275 }
1276
1277 bool CommandLineFlags::_finished_initializing = false;
1278
1279 bool CommandLineFlags::check_all_ranges_and_constraints() {
1280 //#define PRINT_RANGES_AND_CONSTRAINTS_SIZES
1281 #ifdef PRINT_RANGES_AND_CONSTRAINTS_SIZES
1282 {
1283 size_t size_ranges = sizeof(CommandLineFlagRangeList);
1284 for (int i=0; i<CommandLineFlagRangeList::length(); i++) {
1285 size_ranges += sizeof(CommandLineFlagRange);
1286 CommandLineFlagRange* range = CommandLineFlagRangeList::at(i);
1287 const char* name = range->name();
1288 Flag* flag = Flag::find_flag(name, strlen(name), true, true);
1289 if (flag->is_intx()) {
1290 size_ranges += 2*sizeof(intx);
1291 size_ranges += sizeof(CommandLineFlagRange*);
1292 } else if (flag->is_uintx()) {
1293 size_ranges += 2*sizeof(uintx);
1294 size_ranges += sizeof(CommandLineFlagRange*);
1295 } else if (flag->is_uint64_t()) {
1296 size_ranges += 2*sizeof(uint64_t);
1297 size_ranges += sizeof(CommandLineFlagRange*);
1298 } else if (flag->is_size_t()) {
1299 size_ranges += 2*sizeof(size_t);
1405 #endif // PRODUCT
1406
1407 #define ONLY_PRINT_PRODUCT_FLAGS
1408
1409 void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) {
1410 // Print the flags sorted by name
1411 // note: this method is called before the thread structure is in place
1412 // which means resource allocation cannot be used.
1413
1414 // The last entry is the null entry.
1415 const size_t length = Flag::numFlags - 1;
1416
1417 // Sort
1418 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1419 for (size_t i = 0; i < length; i++) {
1420 array[i] = &flagTable[i];
1421 }
1422 qsort(array, length, sizeof(Flag*), compare_flags);
1423
1424 // Print
1425 if (printRanges == false) {
1426 out->print_cr("[Global flags]");
1427 } else {
1428 out->print_cr("[Global flags ranges]");
1429 }
1430
1431 for (size_t i = 0; i < length; i++) {
1432 if (array[i]->is_unlocked()) {
1433 #ifdef ONLY_PRINT_PRODUCT_FLAGS
1434 if (!array[i]->is_notproduct() && !array[i]->is_develop())
1435 #endif // ONLY_PRINT_PRODUCT_FLAGS
1436 array[i]->print_on(out, printRanges, withComments);
1437 }
1438 }
1439 FREE_C_HEAP_ARRAY(Flag*, array);
1440 }
|
331 }
332 get_locked_message_ext(buf, buflen);
333 }
334
335 bool Flag::is_writeable() const {
336 return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
337 }
338
339 // All flags except "manageable" are assumed to be internal flags.
340 // Long term, we need to define a mechanism to specify which flags
341 // are external/stable and change this function accordingly.
342 bool Flag::is_external() const {
343 return is_manageable() || is_external_ext();
344 }
345
346
347 // Length of format string (e.g. "%.1234s") for printing ccstr below
348 #define FORMAT_BUFFER_LEN 16
349
350 PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
351 void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
352 // Don't print notproduct and develop flags in a product build.
353 if (is_constant_in_binary()) {
354 return;
355 }
356
357 if (!printRanges) {
358
359 st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
360
361 if (is_bool()) {
362 st->print("%-16s", get_bool() ? "true" : "false");
363 } else if (is_int()) {
364 st->print("%-16d", get_int());
365 } else if (is_uint()) {
366 st->print("%-16u", get_uint());
367 } else if (is_intx()) {
368 st->print("%-16ld", get_intx());
369 } else if (is_uintx()) {
370 st->print("%-16lu", get_uintx());
371 } else if (is_uint64_t()) {
637 FLAGTABLE_EXT
638 {0, NULL, NULL}
639 };
640
641 Flag* Flag::flags = flagTable;
642 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
643
644 inline bool str_equal(const char* s, const char* q, size_t len) {
645 // s is null terminated, q is not!
646 if (strlen(s) != (unsigned int) len) return false;
647 return strncmp(s, q, len) == 0;
648 }
649
650 // Search the flag table for a named flag
651 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
652 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
653 if (str_equal(current->_name, name, length)) {
654 // Found a matching entry.
655 // Don't report notproduct and develop flags in product builds.
656 if (current->is_constant_in_binary()) {
657 return (return_flag ? current : NULL);
658 }
659 // Report locked flags only if allowed.
660 if (!(current->is_unlocked() || current->is_unlocker())) {
661 if (!allow_locked) {
662 // disable use of locked flags, e.g. diagnostic, experimental,
663 // commercial... until they are explicitly unlocked
664 return NULL;
665 }
666 }
667 return current;
668 }
669 }
670 // Flag name is not in the flag table
671 return NULL;
672 }
673
674 // Compute string similarity based on Dice's coefficient
675 static float str_similar(const char* str1, const char* str2, size_t len2) {
676 int len1 = (int) strlen(str1);
677 int total = len1 + (int) len2;
741 return f->is_command_line();
742 }
743
744 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
745 Flag* result = Flag::find_flag((char*)name, strlen(name));
746 if (result == NULL) return false;
747 *value = result->is_command_line();
748 return true;
749 }
750
751 template<class E, class T>
752 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) {
753 E e;
754 e.set_name(name);
755 e.set_old_value(old_value);
756 e.set_new_value(new_value);
757 e.set_origin(origin);
758 e.commit();
759 }
760
761 static Flag::Error get_status_error(Flag::Error status_range, Flag::Error status_constraint) {
762 if (status_range != Flag::SUCCESS) {
763 return status_range;
764 } else if (status_constraint != Flag::SUCCESS) {
765 return status_constraint;
766 } else {
767 return Flag::SUCCESS;
768 }
769 }
770
771 static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool* new_value, bool verbose = true) {
772 Flag::Error status = Flag::SUCCESS;
773 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
774 if (constraint != NULL) {
775 status = constraint->apply_bool(new_value, verbose);
776 }
777 return status;
778 }
779
780 Flag::Error CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) {
781 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
782 if (result == NULL) return Flag::INVALID_FLAG;
783 if (!result->is_bool()) return Flag::WRONG_FORMAT;
784 *value = result->get_bool();
785 return Flag::SUCCESS;
786 }
787
788 Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
789 Flag* result = Flag::find_flag(name, len);
790 if (result == NULL) return Flag::INVALID_FLAG;
794 bool old_value = result->get_bool();
795 trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
796 result->set_bool(*value);
797 *value = old_value;
798 result->set_origin(origin);
799 return Flag::SUCCESS;
800 }
801
802 Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
803 Flag* faddr = address_of_flag(flag);
804 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
805 Flag::Error check = apply_constraint_and_check_range_bool(faddr->_name, &value);
806 if (check != Flag::SUCCESS) return check;
807 trace_flag_changed<EventBooleanFlagChanged, bool>(faddr->_name, faddr->get_bool(), value, origin);
808 faddr->set_bool(value);
809 faddr->set_origin(origin);
810 return Flag::SUCCESS;
811 }
812
813 static Flag::Error apply_constraint_and_check_range_int(const char* name, int* new_value, bool verbose = true) {
814 Flag::Error range_status = Flag::SUCCESS;
815 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
816 if (range != NULL) {
817 range_status = range->check_int(*new_value, verbose);
818 }
819 Flag::Error constraint_status = Flag::SUCCESS;
820 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
821 if (constraint != NULL) {
822 constraint_status = constraint->apply_int(new_value, verbose);
823 }
824 return get_status_error(range_status, constraint_status);
825 }
826
827 Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
828 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
829 if (result == NULL) return Flag::INVALID_FLAG;
830 if (!result->is_int()) return Flag::WRONG_FORMAT;
831 *value = result->get_int();
832 return Flag::SUCCESS;
833 }
834
835 Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
836 Flag* result = Flag::find_flag(name, len);
837 if (result == NULL) return Flag::INVALID_FLAG;
838 if (!result->is_int()) return Flag::WRONG_FORMAT;
839 Flag::Error check = apply_constraint_and_check_range_int(name, value, !CommandLineFlags::finishedInitializing());
840 if (check != Flag::SUCCESS) return check;
841 int old_value = result->get_int();
842 trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
843 result->set_int(*value);
844 *value = old_value;
845 result->set_origin(origin);
846 return Flag::SUCCESS;
847 }
848
849 Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
850 Flag* faddr = address_of_flag(flag);
851 guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
852 trace_flag_changed<EventIntFlagChanged, s4>(faddr->_name, faddr->get_int(), value, origin);
853 faddr->set_int(value);
854 faddr->set_origin(origin);
855 return Flag::SUCCESS;
856 }
857
858 static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint* new_value, bool verbose = true) {
859 Flag::Error range_status = Flag::SUCCESS;
860 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
861 if (range != NULL) {
862 range_status = range->check_uint(*new_value, verbose);
863 }
864 Flag::Error constraint_status = Flag::SUCCESS;
865 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
866 if (constraint != NULL) {
867 constraint_status = constraint->apply_uint(new_value, verbose);
868 }
869 return get_status_error(range_status, constraint_status);
870 }
871
872 Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
873 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
874 if (result == NULL) return Flag::INVALID_FLAG;
875 if (!result->is_uint()) return Flag::WRONG_FORMAT;
876 *value = result->get_uint();
877 return Flag::SUCCESS;
878 }
879
880 Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
881 Flag* result = Flag::find_flag(name, len);
882 if (result == NULL) return Flag::INVALID_FLAG;
883 if (!result->is_uint()) return Flag::WRONG_FORMAT;
884 Flag::Error check = apply_constraint_and_check_range_uint(name, value, !CommandLineFlags::finishedInitializing());
885 if (check != Flag::SUCCESS) return check;
886 uint old_value = result->get_uint();
887 trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
888 result->set_uint(*value);
889 *value = old_value;
892 }
893
894 Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
895 Flag* faddr = address_of_flag(flag);
896 guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
897 trace_flag_changed<EventUnsignedIntFlagChanged, u4>(faddr->_name, faddr->get_uint(), value, origin);
898 faddr->set_uint(value);
899 faddr->set_origin(origin);
900 return Flag::SUCCESS;
901 }
902
903 Flag::Error CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
904 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
905 if (result == NULL) return Flag::INVALID_FLAG;
906 if (!result->is_intx()) return Flag::WRONG_FORMAT;
907 *value = result->get_intx();
908 return Flag::SUCCESS;
909 }
910
911 static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx* new_value, bool verbose = true) {
912 Flag::Error range_status = Flag::SUCCESS;
913 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
914 if (range != NULL) {
915 range_status = range->check_intx(*new_value, verbose);
916 }
917 Flag::Error constraint_status = Flag::SUCCESS;
918 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
919 if (constraint != NULL) {
920 constraint_status = constraint->apply_intx(new_value, verbose);
921 }
922 return get_status_error(range_status, constraint_status);
923 }
924
925 Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
926 Flag* result = Flag::find_flag(name, len);
927 if (result == NULL) return Flag::INVALID_FLAG;
928 if (!result->is_intx()) return Flag::WRONG_FORMAT;
929 Flag::Error check = apply_constraint_and_check_range_intx(name, value, !CommandLineFlags::finishedInitializing());
930 if (check != Flag::SUCCESS) return check;
931 intx old_value = result->get_intx();
932 trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
933 result->set_intx(*value);
934 *value = old_value;
935 result->set_origin(origin);
936 return Flag::SUCCESS;
937 }
938
939 Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
940 Flag* faddr = address_of_flag(flag);
941 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
942 Flag::Error check = apply_constraint_and_check_range_intx(faddr->_name, &value);
943 if (check != Flag::SUCCESS) return check;
944 trace_flag_changed<EventLongFlagChanged, intx>(faddr->_name, faddr->get_intx(), value, origin);
945 faddr->set_intx(value);
946 faddr->set_origin(origin);
947 return Flag::SUCCESS;
948 }
949
950 Flag::Error CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
951 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
952 if (result == NULL) return Flag::INVALID_FLAG;
953 if (!result->is_uintx()) return Flag::WRONG_FORMAT;
954 *value = result->get_uintx();
955 return Flag::SUCCESS;
956 }
957
958 static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx* new_value, bool verbose = true) {
959 Flag::Error range_status = Flag::SUCCESS;
960 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
961 if (range != NULL) {
962 range_status = range->check_uintx(*new_value, verbose);
963 }
964 Flag::Error constraint_status = Flag::SUCCESS;
965 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
966 if (constraint != NULL) {
967 constraint_status = constraint->apply_uintx(new_value, verbose);
968 }
969 return get_status_error(range_status, constraint_status);
970 }
971
972 Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
973 Flag* result = Flag::find_flag(name, len);
974 if (result == NULL) return Flag::INVALID_FLAG;
975 if (!result->is_uintx()) return Flag::WRONG_FORMAT;
976 Flag::Error check = apply_constraint_and_check_range_uintx(name, value, !CommandLineFlags::finishedInitializing());
977 if (check != Flag::SUCCESS) return check;
978 uintx old_value = result->get_uintx();
979 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
980 result->set_uintx(*value);
981 *value = old_value;
982 result->set_origin(origin);
983 return Flag::SUCCESS;
984 }
985
986 Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
987 Flag* faddr = address_of_flag(flag);
988 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
989 Flag::Error check = apply_constraint_and_check_range_uintx(faddr->_name, &value);
990 if (check != Flag::SUCCESS) return check;
991 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uintx(), value, origin);
992 faddr->set_uintx(value);
993 faddr->set_origin(origin);
994 return Flag::SUCCESS;
995 }
996
997 Flag::Error CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
998 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
999 if (result == NULL) return Flag::INVALID_FLAG;
1000 if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
1001 *value = result->get_uint64_t();
1002 return Flag::SUCCESS;
1003 }
1004
1005 static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t* new_value, bool verbose = true) {
1006 Flag::Error range_status = Flag::SUCCESS;
1007 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1008 if (range != NULL) {
1009 range_status = range->check_uint64_t(*new_value, verbose);
1010 }
1011 Flag::Error constraint_status = Flag::SUCCESS;
1012 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
1013 if (constraint != NULL) {
1014 constraint_status = constraint->apply_uint64_t(new_value, verbose);
1015 }
1016 return get_status_error(range_status, constraint_status);
1017 }
1018
1019 Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
1020 Flag* result = Flag::find_flag(name, len);
1021 if (result == NULL) return Flag::INVALID_FLAG;
1022 if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
1023 Flag::Error check = apply_constraint_and_check_range_uint64_t(name, value, !CommandLineFlags::finishedInitializing());
1024 if (check != Flag::SUCCESS) return check;
1025 uint64_t old_value = result->get_uint64_t();
1026 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1027 result->set_uint64_t(*value);
1028 *value = old_value;
1029 result->set_origin(origin);
1030 return Flag::SUCCESS;
1031 }
1032
1033 Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
1034 Flag* faddr = address_of_flag(flag);
1035 guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
1036 Flag::Error check = apply_constraint_and_check_range_uint64_t(faddr->_name, &value);
1037 if (check != Flag::SUCCESS) return check;
1038 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uint64_t(), value, origin);
1039 faddr->set_uint64_t(value);
1040 faddr->set_origin(origin);
1041 return Flag::SUCCESS;
1042 }
1043
1044 Flag::Error CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
1045 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1046 if (result == NULL) return Flag::INVALID_FLAG;
1047 if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1048 *value = result->get_size_t();
1049 return Flag::SUCCESS;
1050 }
1051
1052 static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t* new_value, bool verbose = true) {
1053 Flag::Error range_status = Flag::SUCCESS;
1054 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1055 if (range != NULL) {
1056 range_status = range->check_size_t(*new_value, verbose);
1057 }
1058 Flag::Error constraint_status = Flag::SUCCESS;
1059 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
1060 if (constraint != NULL) {
1061 constraint_status = constraint->apply_size_t(new_value, verbose);
1062 }
1063 return get_status_error(range_status, constraint_status);
1064 }
1065
1066 Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
1067 Flag* result = Flag::find_flag(name, len);
1068 if (result == NULL) return Flag::INVALID_FLAG;
1069 if (!result->is_size_t()) return Flag::WRONG_FORMAT;
1070 Flag::Error check = apply_constraint_and_check_range_size_t(name, value, !CommandLineFlags::finishedInitializing());
1071 if (check != Flag::SUCCESS) return check;
1072 size_t old_value = result->get_size_t();
1073 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
1074 result->set_size_t(*value);
1075 *value = old_value;
1076 result->set_origin(origin);
1077 return Flag::SUCCESS;
1078 }
1079
1080 Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
1081 Flag* faddr = address_of_flag(flag);
1082 guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
1083 Flag::Error check = apply_constraint_and_check_range_size_t(faddr->_name, &value);
1084 if (check != Flag::SUCCESS) return check;
1085 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_size_t(), value, origin);
1086 faddr->set_size_t(value);
1087 faddr->set_origin(origin);
1088 return Flag::SUCCESS;
1089 }
1090
1091 Flag::Error CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
1092 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
1093 if (result == NULL) return Flag::INVALID_FLAG;
1094 if (!result->is_double()) return Flag::WRONG_FORMAT;
1095 *value = result->get_double();
1096 return Flag::SUCCESS;
1097 }
1098
1099 static Flag::Error apply_constraint_and_check_range_double(const char* name, double* new_value, bool verbose = true) {
1100 Flag::Error range_status = Flag::SUCCESS;
1101 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
1102 if (range != NULL) {
1103 range_status = range->check_double(*new_value, verbose);
1104 }
1105 Flag::Error constraint_status = Flag::SUCCESS;
1106 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
1107 if (constraint != NULL) {
1108 constraint_status = constraint->apply_double(new_value, verbose);
1109 }
1110 return get_status_error(range_status, constraint_status);
1111 }
1112
1113 Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
1114 Flag* result = Flag::find_flag(name, len);
1115 if (result == NULL) return Flag::INVALID_FLAG;
1116 if (!result->is_double()) return Flag::WRONG_FORMAT;
1117 Flag::Error check = apply_constraint_and_check_range_double(name, value, !CommandLineFlags::finishedInitializing());
1118 if (check != Flag::SUCCESS) return check;
1119 double old_value = result->get_double();
1120 trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
1121 result->set_double(*value);
1122 *value = old_value;
1123 result->set_origin(origin);
1124 return Flag::SUCCESS;
1125 }
1126
1127 Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
1128 Flag* faddr = address_of_flag(flag);
1129 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
1130 Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, &value, !CommandLineFlags::finishedInitializing());
1161 *value = old_value;
1162 result->set_origin(origin);
1163 return Flag::SUCCESS;
1164 }
1165
1166 Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
1167 Flag* faddr = address_of_flag(flag);
1168 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
1169 ccstr old_value = faddr->get_ccstr();
1170 trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
1171 char* new_value = os::strdup_check_oom(value);
1172 faddr->set_ccstr(new_value);
1173 if (!faddr->is_default() && old_value != NULL) {
1174 // Prior value is heap allocated so free it.
1175 FREE_C_HEAP_ARRAY(char, old_value);
1176 }
1177 faddr->set_origin(origin);
1178 return Flag::SUCCESS;
1179 }
1180
1181 extern "C" {
1182 static int compare_flags(const void* void_a, const void* void_b) {
1183 return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
1184 }
1185 }
1186
1187 void CommandLineFlags::printSetFlags(outputStream* out) {
1188 // Print which flags were set on the command line
1189 // note: this method is called before the thread structure is in place
1190 // which means resource allocation cannot be used.
1191
1192 // The last entry is the null entry.
1193 const size_t length = Flag::numFlags - 1;
1194
1195 // Sort
1196 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1197 for (size_t i = 0; i < length; i++) {
1198 array[i] = &flagTable[i];
1199 }
1200 qsort(array, length, sizeof(Flag*), compare_flags);
1201
1202 // Print
1203 for (size_t i = 0; i < length; i++) {
1204 if (array[i]->get_origin() /* naked field! */) {
1205 array[i]->print_as_flag(out);
1206 out->print(" ");
1207 }
1208 }
1209 out->cr();
1210 FREE_C_HEAP_ARRAY(Flag*, array);
1211 }
1212
1213 bool CommandLineFlags::_finished_initializing = false;
1214
1215 bool CommandLineFlags::check_all_ranges_and_constraints() {
1216
1217 //#define PRINT_RANGES_AND_CONSTRAINTS_SIZES
1218 #ifdef PRINT_RANGES_AND_CONSTRAINTS_SIZES
1219 {
1220 size_t size_ranges = sizeof(CommandLineFlagRangeList);
1221 for (int i=0; i<CommandLineFlagRangeList::length(); i++) {
1222 size_ranges += sizeof(CommandLineFlagRange);
1223 CommandLineFlagRange* range = CommandLineFlagRangeList::at(i);
1224 const char* name = range->name();
1225 Flag* flag = Flag::find_flag(name, strlen(name), true, true);
1226 if (flag->is_intx()) {
1227 size_ranges += 2*sizeof(intx);
1228 size_ranges += sizeof(CommandLineFlagRange*);
1229 } else if (flag->is_uintx()) {
1230 size_ranges += 2*sizeof(uintx);
1231 size_ranges += sizeof(CommandLineFlagRange*);
1232 } else if (flag->is_uint64_t()) {
1233 size_ranges += 2*sizeof(uint64_t);
1234 size_ranges += sizeof(CommandLineFlagRange*);
1235 } else if (flag->is_size_t()) {
1236 size_ranges += 2*sizeof(size_t);
1342 #endif // PRODUCT
1343
1344 #define ONLY_PRINT_PRODUCT_FLAGS
1345
1346 void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) {
1347 // Print the flags sorted by name
1348 // note: this method is called before the thread structure is in place
1349 // which means resource allocation cannot be used.
1350
1351 // The last entry is the null entry.
1352 const size_t length = Flag::numFlags - 1;
1353
1354 // Sort
1355 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
1356 for (size_t i = 0; i < length; i++) {
1357 array[i] = &flagTable[i];
1358 }
1359 qsort(array, length, sizeof(Flag*), compare_flags);
1360
1361 // Print
1362 if (!printRanges) {
1363 out->print_cr("[Global flags]");
1364 } else {
1365 out->print_cr("[Global flags ranges]");
1366 }
1367
1368 for (size_t i = 0; i < length; i++) {
1369 if (array[i]->is_unlocked()) {
1370 #ifdef ONLY_PRINT_PRODUCT_FLAGS
1371 if (!array[i]->is_notproduct() && !array[i]->is_develop())
1372 #endif // ONLY_PRINT_PRODUCT_FLAGS
1373 array[i]->print_on(out, withComments, printRanges);
1374 }
1375 }
1376 FREE_C_HEAP_ARRAY(Flag*, array);
1377 }
|