comparison src/share/vm/graal/graalRuntime.cpp @ 21519:cecb4e39521c

Use files in lib/graal/options to define Graal options (-G:...) instead of generating code for them
author Gilles Duboscq <gilles.m.duboscq@oracle.com>
date Wed, 27 May 2015 17:40:26 +0200
parents fe4a77bec5b7
children fad971028755
comparison
equal deleted inserted replaced
21518:c2e58b2a2a76 21519:cecb4e39521c
35 #include "runtime/biasedLocking.hpp" 35 #include "runtime/biasedLocking.hpp"
36 #include "runtime/interfaceSupport.hpp" 36 #include "runtime/interfaceSupport.hpp"
37 #include "runtime/arguments.hpp" 37 #include "runtime/arguments.hpp"
38 #include "runtime/reflection.hpp" 38 #include "runtime/reflection.hpp"
39 #include "utilities/debug.hpp" 39 #include "utilities/debug.hpp"
40 #include "utilities/defaultStream.hpp"
40 41
41 jobject GraalRuntime::_HotSpotGraalRuntime_instance = NULL; 42 jobject GraalRuntime::_HotSpotGraalRuntime_instance = NULL;
42 bool GraalRuntime::_HotSpotGraalRuntime_initialized = false; 43 bool GraalRuntime::_HotSpotGraalRuntime_initialized = false;
43 bool GraalRuntime::_shutdown_called = false; 44 bool GraalRuntime::_shutdown_called = false;
44 45
623 SystemDictionary::init_graal_loader(JNIHandles::resolve(loader_handle)); 624 SystemDictionary::init_graal_loader(JNIHandles::resolve(loader_handle));
624 SystemDictionary::WKID scan = SystemDictionary::FIRST_GRAAL_WKID; 625 SystemDictionary::WKID scan = SystemDictionary::FIRST_GRAAL_WKID;
625 SystemDictionary::initialize_wk_klasses_through(SystemDictionary::LAST_GRAAL_WKID, scan, CHECK); 626 SystemDictionary::initialize_wk_klasses_through(SystemDictionary::LAST_GRAAL_WKID, scan, CHECK);
626 JVM_END 627 JVM_END
627 628
629 // boolean com.oracle.graal.hotspot.HotSpotOptions.isCITimingEnabled()
630 JVM_ENTRY(jboolean, JVM_IsCITimingEnabled(JNIEnv *env, jclass c))
631 return CITime || CITimeEach;
632 JVM_END
633
628 // private static GraalRuntime Graal.initializeRuntime() 634 // private static GraalRuntime Graal.initializeRuntime()
629 JVM_ENTRY(jobject, JVM_GetGraalRuntime(JNIEnv *env, jclass c)) 635 JVM_ENTRY(jobject, JVM_GetGraalRuntime(JNIEnv *env, jclass c))
630 GraalRuntime::initialize_HotSpotGraalRuntime(); 636 GraalRuntime::initialize_HotSpotGraalRuntime();
631 return GraalRuntime::get_HotSpotGraalRuntime_jobject(); 637 return GraalRuntime::get_HotSpotGraalRuntime_jobject();
632 JVM_END 638 JVM_END
663 JavaValue result(T_OBJECT); 669 JavaValue result(T_OBJECT);
664 JavaCalls::call_static(&result, klass, makeInstance, sig, CHECK_NULL); 670 JavaCalls::call_static(&result, klass, makeInstance, sig, CHECK_NULL);
665 return JNIHandles::make_local(THREAD, (oop) result.get_jobject()); 671 return JNIHandles::make_local(THREAD, (oop) result.get_jobject());
666 JVM_END 672 JVM_END
667 673
668 void GraalRuntime::check_generated_sources_sha1(TRAPS) {
669 TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/sourcegen/GeneratedSourcesSha1", CHECK_ABORT);
670 KlassHandle klass = load_required_class(name);
671 fieldDescriptor fd;
672 if (!InstanceKlass::cast(klass())->find_field(vmSymbols::value_name(), vmSymbols::string_signature(), true, &fd)) {
673 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), "GeneratedSourcesSha1.value");
674 }
675
676 Symbol* value = java_lang_String::as_symbol(klass->java_mirror()->obj_field(fd.offset()), CHECK);
677 if (!value->equals(_generated_sources_sha1)) {
678 char buf[200];
679 jio_snprintf(buf, sizeof(buf), "Generated sources SHA1 check failed (%s != %s) - need to rebuild the VM", value->as_C_string(), _generated_sources_sha1);
680 THROW_MSG(vmSymbols::java_lang_InternalError(), buf);
681 }
682 }
683
684 Handle GraalRuntime::callInitializer(const char* className, const char* methodName, const char* returnType) { 674 Handle GraalRuntime::callInitializer(const char* className, const char* methodName, const char* returnType) {
685 guarantee(!_HotSpotGraalRuntime_initialized, "cannot reinitialize HotSpotGraalRuntime"); 675 guarantee(!_HotSpotGraalRuntime_initialized, "cannot reinitialize HotSpotGraalRuntime");
686 Thread* THREAD = Thread::current(); 676 Thread* THREAD = Thread::current();
687 check_generated_sources_sha1(CHECK_ABORT_(Handle()));
688 677
689 TempNewSymbol name = SymbolTable::new_symbol(className, CHECK_ABORT_(Handle())); 678 TempNewSymbol name = SymbolTable::new_symbol(className, CHECK_ABORT_(Handle()));
690 KlassHandle klass = load_required_class(name); 679 KlassHandle klass = load_required_class(name);
691 TempNewSymbol runtime = SymbolTable::new_symbol(methodName, CHECK_ABORT_(Handle())); 680 TempNewSymbol runtime = SymbolTable::new_symbol(methodName, CHECK_ABORT_(Handle()));
692 TempNewSymbol sig = SymbolTable::new_symbol(returnType, CHECK_ABORT_(Handle())); 681 TempNewSymbol sig = SymbolTable::new_symbol(returnType, CHECK_ABORT_(Handle()));
722 711
723 // private static void CompilerToVMImpl.init() 712 // private static void CompilerToVMImpl.init()
724 JVM_ENTRY(void, JVM_InitializeGraalNatives(JNIEnv *env, jclass c2vmClass)) 713 JVM_ENTRY(void, JVM_InitializeGraalNatives(JNIEnv *env, jclass c2vmClass))
725 GraalRuntime::initialize_natives(env, c2vmClass); 714 GraalRuntime::initialize_natives(env, c2vmClass);
726 JVM_END 715 JVM_END
727
728 // private static boolean HotSpotOptions.parseVMOptions()
729 JVM_ENTRY(jboolean, JVM_ParseGraalOptions(JNIEnv *env, jclass c))
730 HandleMark hm;
731 KlassHandle hotSpotOptionsClass(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(c)));
732 bool result = GraalRuntime::parse_arguments(hotSpotOptionsClass, CHECK_false);
733 return result;
734 JVM_END
735
736 716
737 void GraalRuntime::ensure_graal_class_loader_is_initialized() { 717 void GraalRuntime::ensure_graal_class_loader_is_initialized() {
738 // This initialization code is guarded by a static pointer to the Factory class. 718 // This initialization code is guarded by a static pointer to the Factory class.
739 // Once it is non-null, the Graal class loader and well known Graal classes are 719 // Once it is non-null, the Graal class loader and well known Graal classes are
740 // guaranteed to have been initialized. By going through the static 720 // guaranteed to have been initialized. By going through the static
770 InstanceKlass* ik = InstanceKlass::cast(klass()); 750 InstanceKlass* ik = InstanceKlass::cast(klass());
771 address addr = ik->static_field_addr(field_desc.offset() - InstanceMirrorKlass::offset_of_static_fields()); 751 address addr = ik->static_field_addr(field_desc.offset() - InstanceMirrorKlass::offset_of_static_fields());
772 *((jboolean *) addr) = (jboolean) UseGraalClassLoader; 752 *((jboolean *) addr) = (jboolean) UseGraalClassLoader;
773 klass->initialize(CHECK_ABORT); 753 klass->initialize(CHECK_ABORT);
774 _FactoryKlass = klass(); 754 _FactoryKlass = klass();
775 } 755 assert(!UseGraalClassLoader || SystemDictionary::graal_loader() != NULL, "Graal classloader should have been initialized");
776 } 756 }
777 757 }
778 jint GraalRuntime::check_arguments(TRAPS) { 758
779 KlassHandle nullHandle; 759 OptionsValueTable* GraalRuntime::parse_arguments() {
780 parse_arguments(nullHandle, THREAD); 760 OptionsTable* table = OptionsTable::load_options();
781 if (HAS_PENDING_EXCEPTION) { 761 if (table == NULL) {
782 // Errors in parsing Graal arguments cause exceptions. 762 return NULL;
783 // We now load and initialize HotSpotOptions which in turn 763 }
784 // causes argument parsing to be redone with better error messages. 764
785 CLEAR_PENDING_EXCEPTION; 765 OptionsValueTable* options = new OptionsValueTable(table);
786 TempNewSymbol name = SymbolTable::new_symbol("Lcom/oracle/graal/hotspot/HotSpotOptions;", CHECK_ABORT_(JNI_ERR));
787 instanceKlassHandle hotSpotOptionsClass = resolve_or_fail(name, CHECK_ABORT_(JNI_ERR));
788
789 parse_arguments(hotSpotOptionsClass, THREAD);
790 assert(HAS_PENDING_EXCEPTION, "must be");
791
792 ResourceMark rm;
793 Handle exception = PENDING_EXCEPTION;
794 CLEAR_PENDING_EXCEPTION;
795 oop message = java_lang_Throwable::message(exception);
796 if (message != NULL) {
797 tty->print_cr("Error parsing Graal options: %s", java_lang_String::as_utf8_string(message));
798 } else {
799 call_printStackTrace(exception, THREAD);
800 }
801 return JNI_ERR;
802 }
803 return JNI_OK;
804 }
805
806 bool GraalRuntime::parse_arguments(KlassHandle hotSpotOptionsClass, TRAPS) {
807 ResourceMark rm(THREAD);
808 766
809 // Process option overrides from graal.options first 767 // Process option overrides from graal.options first
810 parse_graal_options_file(hotSpotOptionsClass, CHECK_false); 768 parse_graal_options_file(options);
811 769
812 // Now process options on the command line 770 // Now process options on the command line
813 int numOptions = Arguments::num_graal_args(); 771 int numOptions = Arguments::num_graal_args();
814 for (int i = 0; i < numOptions; i++) { 772 for (int i = 0; i < numOptions; i++) {
815 char* arg = Arguments::graal_args_array()[i]; 773 char* arg = Arguments::graal_args_array()[i];
816 parse_argument(hotSpotOptionsClass, arg, CHECK_false); 774 if (!parse_argument(options, arg)) {
817 } 775 delete options;
818 return CITime || CITimeEach; 776 return NULL;
819 } 777 }
820 778 }
821 void GraalRuntime::check_required_value(const char* name, size_t name_len, const char* value, TRAPS) { 779 return options;
822 if (value == NULL) { 780 }
823 char buf[200]; 781
824 jio_snprintf(buf, sizeof(buf), "Must use '-G:%.*s=<value>' format for %.*s option", name_len, name, name_len, name); 782 void not_found(OptionsTable* table, const char* argname, size_t namelen) {
825 THROW_MSG(vmSymbols::java_lang_InternalError(), buf); 783 jio_fprintf(defaultStream::error_stream(),"Unrecognized VM option '%.*s'\n", namelen, argname);
826 } 784 OptionDesc* fuzzy_matched = table->fuzzy_match(argname, strlen(argname));
827 } 785 if (fuzzy_matched != NULL) {
828 786 jio_fprintf(defaultStream::error_stream(),
829 void GraalRuntime::parse_argument(KlassHandle hotSpotOptionsClass, char* arg, TRAPS) { 787 "Did you mean '%s%s%s'?\n",
830 ensure_graal_class_loader_is_initialized(); 788 (fuzzy_matched->type == _boolean) ? "(+/-)" : "",
789 fuzzy_matched->name,
790 (fuzzy_matched->type == _boolean) ? "" : "=<value>");
791 }
792 }
793
794 bool GraalRuntime::parse_argument(OptionsValueTable* options, const char* arg) {
795 OptionsTable* table = options->options_table();
831 char first = arg[0]; 796 char first = arg[0];
832 char* name; 797 const char* name;
833 size_t name_len; 798 size_t name_len;
834 bool recognized = true;
835 if (first == '+' || first == '-') { 799 if (first == '+' || first == '-') {
836 name = arg + 1; 800 name = arg + 1;
837 name_len = strlen(name); 801 OptionDesc* optionDesc = table->get(name);
838 recognized = set_option_bool(hotSpotOptionsClass, name, name_len, first, CHECK); 802 if (optionDesc == NULL) {
803 not_found(table, name, strlen(name));
804 return false;
805 }
806 if (optionDesc->type != _boolean) {
807 jio_fprintf(defaultStream::error_stream(), "Unexpected +/- setting in VM option '%s'\n", name);
808 return false;
809 }
810 OptionValue value;
811 value.desc = *optionDesc;
812 value.boolean_value = first == '+';
813 options->put(value);
814 return true;
839 } else { 815 } else {
840 char* sep = strchr(arg, '='); 816 const char* sep = strchr(arg, '=');
841 name = arg; 817 name = arg;
842 char* value = NULL; 818 const char* value = NULL;
843 if (sep != NULL) { 819 if (sep != NULL) {
844 name_len = sep - name; 820 name_len = sep - name;
845 value = sep + 1; 821 value = sep + 1;
846 } else { 822 } else {
847 name_len = strlen(name); 823 name_len = strlen(name);
848 } 824 }
849 recognized = set_option(hotSpotOptionsClass, name, name_len, value, CHECK); 825 OptionDesc* optionDesc = table->get(name, name_len);
850 } 826 if (optionDesc == NULL) {
851 827 not_found(table, name, name_len);
852 if (!recognized) { 828 return false;
853 bool throw_err = hotSpotOptionsClass.is_null(); 829 }
854 if (!hotSpotOptionsClass.is_null()) { 830 if (optionDesc->type == _boolean) {
855 set_option_helper(hotSpotOptionsClass, name, name_len, Handle(), ' ', Handle(), 0L); 831 jio_fprintf(defaultStream::error_stream(), "Missing +/- setting for VM option '%s'\n", name);
856 if (!HAS_PENDING_EXCEPTION) { 832 return false;
857 throw_err = true; 833 }
834 if (value == NULL) {
835 jio_fprintf(defaultStream::error_stream(), "Must use '-G:%.*s=<value>' format for %.*s option", name_len, name, name_len, name);
836 return false;
837 }
838 OptionValue optionValue;
839 optionValue.desc = *optionDesc;
840 char* check;
841 errno = 0;
842 switch(optionDesc->type) {
843 case _int: {
844 long int int_value = ::strtol(value, &check, 10);
845 if (*check != '\0' || errno == ERANGE || int_value > max_jint || int_value < min_jint) {
846 jio_fprintf(defaultStream::error_stream(), "Expected int value for VM option '%s'\n", name);
847 return false;
848 }
849 optionValue.int_value = int_value;
850 break;
858 } 851 }
859 } 852 case _long: {
860 853 long long int long_value = ::strtoll(value, &check, 10);
861 if (throw_err) { 854 if (*check != '\0' || errno == ERANGE || long_value > max_jlong || long_value < min_jlong) {
862 char buf[200]; 855 jio_fprintf(defaultStream::error_stream(), "Expected long value for VM option '%s'\n", name);
863 jio_snprintf(buf, sizeof(buf), "Unrecognized Graal option %.*s", name_len, name); 856 return false;
864 THROW_MSG(vmSymbols::java_lang_InternalError(), buf); 857 }
865 } 858 optionValue.long_value = long_value;
859 break;
860 }
861 case _float: {
862 optionValue.float_value = ::strtof(value, &check);
863 if (*check != '\0' || errno == ERANGE) {
864 jio_fprintf(defaultStream::error_stream(), "Expected float value for VM option '%s'\n", name);
865 return false;
866 }
867 break;
868 }
869 case _double: {
870 optionValue.double_value = ::strtod(value, &check);
871 if (*check != '\0' || errno == ERANGE) {
872 jio_fprintf(defaultStream::error_stream(), "Expected double value for VM option '%s'\n", name);
873 return false;
874 }
875 break;
876 }
877 case _string: {
878 char* copy = NEW_C_HEAP_ARRAY(char, strlen(value) + 1, mtCompiler);
879 strcpy(copy, value);
880 optionValue.string_value = copy;
881 break;
882 }
883 default:
884 ShouldNotReachHere();
885 }
886 options->put(optionValue);
887 return true;
866 } 888 }
867 } 889 }
868 890
869 class GraalOptionParseClosure : public ParseClosure { 891 class GraalOptionParseClosure : public ParseClosure {
870 TRAPS; 892 OptionsValueTable* _options;
871 KlassHandle _hotSpotOptionsClass;
872 public: 893 public:
873 GraalOptionParseClosure(KlassHandle hotSpotOptionsClass, TRAPS) : THREAD(THREAD), _hotSpotOptionsClass(hotSpotOptionsClass) {} 894 GraalOptionParseClosure(OptionsValueTable* options) : _options(options) {}
874 void do_line(char* line) { 895 void do_line(char* line) {
875 GraalRuntime::parse_argument(_hotSpotOptionsClass, line, THREAD); 896 if (!GraalRuntime::parse_argument(_options, line)) {
876 if (HAS_PENDING_EXCEPTION) { 897 warn("There was an error parsing an argument. Skipping it.");
877 warn_and_abort("Exception thrown while parsing argument");
878 } 898 }
879 } 899 }
880 }; 900 };
881 901
882 void GraalRuntime::parse_graal_options_file(KlassHandle hotSpotOptionsClass, TRAPS) { 902 void GraalRuntime::parse_graal_options_file(OptionsValueTable* options) {
883 const char* home = Arguments::get_java_home(); 903 const char* home = Arguments::get_java_home();
884 size_t path_len = strlen(home) + strlen("/lib/graal.options") + 1; 904 size_t path_len = strlen(home) + strlen("/lib/graal.options") + 1;
885 char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len); 905 char path[JVM_MAXPATHLEN];
886 char sep = os::file_separator()[0]; 906 char sep = os::file_separator()[0];
887 sprintf(path, "%s%clib%cgraal.options", home, sep, sep); 907 jio_snprintf(path, JVM_MAXPATHLEN, "%s%clib%cgraal.options", home, sep, sep);
888 GraalOptionParseClosure closure(hotSpotOptionsClass, THREAD); 908 GraalOptionParseClosure closure(options);
889 parse_lines(path, &closure, false, THREAD); 909 parse_lines(path, &closure, false);
890 } 910 }
891 911
892 jlong GraalRuntime::parse_primitive_option_value(char spec, const char* name, size_t name_len, const char* value, TRAPS) { 912 #define CHECK_WARN_ABORT_(message) THREAD); \
893 check_required_value(name, name_len, value, CHECK_(0L)); 913 if (HAS_PENDING_EXCEPTION) { \
894 union { 914 warning(message); \
895 jint i; 915 char buf[512]; \
896 jlong l; 916 jio_snprintf(buf, 512, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
897 double d; 917 GraalRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \
898 } uu; 918 return; \
899 uu.l = 0L; 919 } \
900 char dummy; 920 (void)(0
901 switch (spec) { 921
902 case 'd': 922 class SetOptionClosure : public ValueClosure<OptionValue> {
903 case 'f': { 923 Thread* _thread;
904 if (sscanf(value, "%lf%c", &uu.d, &dummy) == 1) { 924 public:
905 return uu.l; 925 SetOptionClosure(TRAPS) : _thread(THREAD) {}
926 void do_value(OptionValue* optionValue) {
927 TRAPS = _thread;
928 const char* declaringClass = optionValue->desc.declaringClass;
929 if (declaringClass == NULL) {
930 // skip PrintFlags pseudo-option
931 return;
932 }
933 const char* fieldName = optionValue->desc.name;
934 const char* fieldClass = optionValue->desc.fieldClass;
935
936 size_t fieldSigLen = 2 + strlen(fieldClass);
937 char* fieldSig = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, fieldSigLen + 1);
938 jio_snprintf(fieldSig, fieldSigLen + 1, "L%s;", fieldClass);
939 for (size_t i = 0; i < fieldSigLen; ++i) {
940 if (fieldSig[i] == '.') {
941 fieldSig[i] = '/';
906 } 942 }
943 }
944 fieldSig[fieldSigLen] = '\0';
945 size_t declaringClassLen = strlen(declaringClass);
946 char* declaringClassBinary = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, declaringClassLen + 1);
947 for (size_t i = 0; i < declaringClassLen; ++i) {
948 if (declaringClass[i] == '.') {
949 declaringClassBinary[i] = '/';
950 } else {
951 declaringClassBinary[i] = declaringClass[i];
952 }
953 }
954 declaringClassBinary[declaringClassLen] = '\0';
955
956 TempNewSymbol name = SymbolTable::new_symbol(declaringClassBinary, CHECK_WARN_ABORT_("Declaring class could not be found"));
957 Klass* klass = GraalRuntime::resolve_or_null(name, CHECK_WARN_ABORT_("Declaring class could not be resolved"));
958
959 if (klass == NULL) {
960 warning("Declaring class for option %s could not be resolved", declaringClass);
961 abort();
962 return;
963 }
964
965 // The class has been loaded so the field and signature should already be in the symbol
966 // table. If they're not there, the field doesn't exist.
967 TempNewSymbol fieldname = SymbolTable::probe(fieldName, (int)strlen(fieldName));
968 TempNewSymbol signame = SymbolTable::probe(fieldSig, (int)fieldSigLen);
969 if (fieldname == NULL || signame == NULL) {
970 warning("Symbols for field for option %s not found (in %s)", fieldName, declaringClass);
971 abort();
972 return;
973 }
974 // Make sure class is initialized before handing id's out to fields
975 klass->initialize(CHECK_WARN_ABORT_("Error while initializing declaring class for option"));
976
977 fieldDescriptor fd;
978 if (!InstanceKlass::cast(klass)->find_field(fieldname, signame, true, &fd)) {
979 warning("Field for option %s not found (in %s)", fieldName, declaringClass);
980 abort();
981 return;
982 }
983 oop value;
984 switch(optionValue->desc.type) {
985 case _boolean: {
986 jvalue jv;
987 jv.z = optionValue->boolean_value;
988 value = java_lang_boxing_object::create(T_BOOLEAN, &jv, THREAD);
907 break; 989 break;
908 } 990 }
909 case 'i': { 991 case _int: {
910 if (sscanf(value, "%d%c", &uu.i, &dummy) == 1) { 992 jvalue jv;
911 return (jlong)uu.i; 993 jv.i = optionValue->int_value;
912 } 994 value = java_lang_boxing_object::create(T_INT, &jv, THREAD);
913 break; 995 break;
914 } 996 }
997 case _long: {
998 jvalue jv;
999 jv.j = optionValue->long_value;
1000 value = java_lang_boxing_object::create(T_LONG, &jv, THREAD);
1001 break;
1002 }
1003 case _float: {
1004 jvalue jv;
1005 jv.f = optionValue->float_value;
1006 value = java_lang_boxing_object::create(T_FLOAT, &jv, THREAD);
1007 break;
1008 }
1009 case _double: {
1010 jvalue jv;
1011 jv.d = optionValue->double_value;
1012 value = java_lang_boxing_object::create(T_DOUBLE, &jv, THREAD);
1013 break;
1014 }
1015 case _string:
1016 value = java_lang_String::create_from_str(optionValue->string_value, THREAD)();
1017 break;
915 default: 1018 default:
916 ShouldNotReachHere(); 1019 ShouldNotReachHere();
917 } 1020 }
918 ResourceMark rm(THREAD); 1021
919 char buf[200]; 1022 oop optionValueOop = klass->java_mirror()->obj_field(fd.offset());
920 bool missing = strlen(value) == 0; 1023
921 if (missing) { 1024 if (optionValueOop == NULL) {
922 jio_snprintf(buf, sizeof(buf), "Missing %s value for Graal option %.*s", (spec == 'i' ? "numeric" : "float/double"), name_len, name); 1025 warning("Option field was null, can not set %s", fieldName);
923 } else { 1026 abort();
924 jio_snprintf(buf, sizeof(buf), "Invalid %s value for Graal option %.*s: %s", (spec == 'i' ? "numeric" : "float/double"), name_len, name, value); 1027 return;
925 } 1028 }
926 THROW_MSG_(vmSymbols::java_lang_InternalError(), buf, 0L); 1029
927 } 1030 if (!InstanceKlass::cast(optionValueOop->klass())->find_field(vmSymbols::value_name(), vmSymbols::object_signature(), false, &fd)) {
928 1031 warning("'Object value' field not found in option class %s, can not set option %s", fieldClass, fieldName);
929 void GraalRuntime::set_option_helper(KlassHandle hotSpotOptionsClass, char* name, size_t name_len, Handle option, jchar spec, Handle stringValue, jlong primitiveValue) { 1032 abort();
930 Thread* THREAD = Thread::current(); 1033 return;
931 Handle name_handle; 1034 }
932 if (name != NULL) { 1035
933 if (strlen(name) > name_len) { 1036 optionValueOop->obj_field_put(fd.offset(), value);
934 // Temporarily replace '=' with NULL to create the Java string for the option name 1037 }
935 char save = name[name_len]; 1038 };
936 name[name_len] = '\0'; 1039
937 name_handle = java_lang_String::create_from_str(name, THREAD); 1040 void GraalRuntime::set_options(OptionsValueTable* options, TRAPS) {
938 name[name_len] = '='; 1041 ensure_graal_class_loader_is_initialized();
939 if (HAS_PENDING_EXCEPTION) { 1042 {
940 return; 1043 ResourceMark rm;
941 } 1044 SetOptionClosure closure(THREAD);
942 } else { 1045 options->for_each(&closure);
943 assert(strlen(name) == name_len, "must be"); 1046 if (closure.is_aborted()) {
944 name_handle = java_lang_String::create_from_str(name, CHECK); 1047 vm_abort(false);
945 } 1048 }
946 } 1049 }
947 1050 OptionValue* printFlags = options->get(PRINT_FLAGS_ARG);
948 TempNewSymbol setOption = SymbolTable::new_symbol("setOption", CHECK); 1051 if (printFlags != NULL && printFlags->boolean_value) {
949 TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;Lcom/oracle/graal/options/OptionValue;CLjava/lang/String;J)V", CHECK); 1052 print_flags_helper(CHECK_ABORT);
1053 }
1054 }
1055
1056 void GraalRuntime::print_flags_helper(TRAPS) {
1057 // TODO(gd) write this in C++?
1058 HandleMark hm(THREAD);
1059 TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", CHECK_ABORT);
1060 KlassHandle hotSpotOptionsClass = load_required_class(name);
1061 TempNewSymbol setOption = SymbolTable::new_symbol("printFlags", CHECK);
950 JavaValue result(T_VOID); 1062 JavaValue result(T_VOID);
951 JavaCallArguments args; 1063 JavaCallArguments args;
952 args.push_oop(name_handle()); 1064 JavaCalls::call_static(&result, hotSpotOptionsClass, setOption, vmSymbols::void_method_signature(), &args, CHECK);
953 args.push_oop(option());
954 args.push_int(spec);
955 args.push_oop(stringValue());
956 args.push_long(primitiveValue);
957 JavaCalls::call_static(&result, hotSpotOptionsClass, setOption, sig, &args, CHECK);
958 }
959
960 Handle GraalRuntime::get_OptionValue(const char* declaringClass, const char* fieldName, const char* fieldSig, TRAPS) {
961 TempNewSymbol name = SymbolTable::new_symbol(declaringClass, CHECK_NH);
962 Klass* klass = resolve_or_fail(name, CHECK_NH);
963
964 // The class has been loaded so the field and signature should already be in the symbol
965 // table. If they're not there, the field doesn't exist.
966 TempNewSymbol fieldname = SymbolTable::probe(fieldName, (int)strlen(fieldName));
967 TempNewSymbol signame = SymbolTable::probe(fieldSig, (int)strlen(fieldSig));
968 if (fieldname == NULL || signame == NULL) {
969 THROW_MSG_(vmSymbols::java_lang_NoSuchFieldError(), (char*) fieldName, Handle());
970 }
971 // Make sure class is initialized before handing id's out to fields
972 klass->initialize(CHECK_NH);
973
974 fieldDescriptor fd;
975 if (!InstanceKlass::cast(klass)->find_field(fieldname, signame, true, &fd)) {
976 THROW_MSG_(vmSymbols::java_lang_NoSuchFieldError(), (char*) fieldName, Handle());
977 }
978
979 Handle ret = klass->java_mirror()->obj_field(fd.offset());
980 return ret;
981 } 1065 }
982 1066
983 Handle GraalRuntime::create_Service(const char* name, TRAPS) { 1067 Handle GraalRuntime::create_Service(const char* name, TRAPS) {
984 TempNewSymbol kname = SymbolTable::new_symbol(name, CHECK_NH); 1068 TempNewSymbol kname = SymbolTable::new_symbol(name, CHECK_NH);
985 Klass* k = resolve_or_fail(kname, CHECK_NH); 1069 Klass* k = resolve_or_fail(kname, CHECK_NH);
1050 vm_abort(false); 1134 vm_abort(false);
1051 } 1135 }
1052 return klass; 1136 return klass;
1053 } 1137 }
1054 1138
1055 void GraalRuntime::parse_lines(char* path, ParseClosure* closure, bool warnStatFailure, TRAPS) { 1139 void GraalRuntime::parse_lines(char* path, ParseClosure* closure, bool warnStatFailure) {
1056 struct stat st; 1140 struct stat st;
1057 if (os::stat(path, &st) == 0) { 1141 if (os::stat(path, &st) == 0 && (st.st_mode & S_IFREG) == S_IFREG) { // exists & is regular file
1058 int file_handle = os::open(path, 0, 0); 1142 int file_handle = os::open(path, 0, 0);
1059 if (file_handle != -1) { 1143 if (file_handle != -1) {
1060 char* buffer = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, st.st_size + 1); 1144 char* buffer = NEW_C_HEAP_ARRAY(char, st.st_size + 1, mtInternal);
1061 int num_read = (int) os::read(file_handle, (char*) buffer, st.st_size); 1145 int num_read = (int) os::read(file_handle, (char*) buffer, st.st_size);
1062 if (num_read == -1) { 1146 if (num_read == -1) {
1063 warning("Error reading file %s due to %s", path, strerror(errno)); 1147 warning("Error reading file %s due to %s", path, strerror(errno));
1064 } else if (num_read != st.st_size) { 1148 } else if (num_read != st.st_size) {
1065 warning("Only read %d of " SIZE_FORMAT " bytes from %s", num_read, (size_t) st.st_size, path); 1149 warning("Only read %d of " SIZE_FORMAT " bytes from %s", num_read, (size_t) st.st_size, path);
1066 } 1150 }
1067 os::close(file_handle); 1151 os::close(file_handle);
1068 closure->set_filename(path); 1152 closure->set_filename(path);
1069 if (num_read == st.st_size) { 1153 if (num_read == st.st_size) {
1070 buffer[num_read] = '\0'; 1154 buffer[num_read] = '\0';
1071 1155
1072 char* line = buffer; 1156 char* line = buffer;
1073 while (line - buffer < num_read && !closure->is_aborted()) { 1157 while (line - buffer < num_read && !closure->is_aborted()) {
1074 // find line end (\r, \n or \r\n) 1158 // find line end (\r, \n or \r\n)
1075 char* nextline = NULL; 1159 char* nextline = NULL;
1076 char* cr = strchr(line, '\r'); 1160 char* cr = strchr(line, '\r');
1077 char* lf = strchr(line, '\n'); 1161 char* lf = strchr(line, '\n');
1078 if (cr != NULL && lf != NULL) { 1162 if (cr != NULL && lf != NULL) {
1079 char* min = MIN2(cr, lf); 1163 char* min = MIN2(cr, lf);
1080 *min = '\0'; 1164 *min = '\0';
1081 if (lf == cr + 1) { 1165 if (lf == cr + 1) {
1082 nextline = lf + 1;
1083 } else {
1084 nextline = min + 1;
1085 }
1086 } else if (cr != NULL) {
1087 *cr = '\0';
1088 nextline = cr + 1;
1089 } else if (lf != NULL) {
1090 *lf = '\0';
1091 nextline = lf + 1; 1166 nextline = lf + 1;
1167 } else {
1168 nextline = min + 1;
1092 } 1169 }
1093 // trim left 1170 } else if (cr != NULL) {
1094 while (*line == ' ' || *line == '\t') line++; 1171 *cr = '\0';
1095 char* end = line + strlen(line); 1172 nextline = cr + 1;
1096 // trim right 1173 } else if (lf != NULL) {
1097 while (end > line && (*(end -1) == ' ' || *(end -1) == '\t')) end--; 1174 *lf = '\0';
1098 *end = '\0'; 1175 nextline = lf + 1;
1099 // skip comments and empty lines 1176 }
1100 if (*line != '#' && strlen(line) > 0) { 1177 // trim left
1101 closure->parse_line(line); 1178 while (*line == ' ' || *line == '\t') line++;
1102 } 1179 char* end = line + strlen(line);
1103 if (nextline != NULL) { 1180 // trim right
1104 line = nextline; 1181 while (end > line && (*(end -1) == ' ' || *(end -1) == '\t')) end--;
1105 } else { 1182 *end = '\0';
1106 // File without newline at the end 1183 // skip comments and empty lines
1107 break; 1184 if (*line != '#' && strlen(line) > 0) {
1108 } 1185 closure->parse_line(line);
1186 }
1187 if (nextline != NULL) {
1188 line = nextline;
1189 } else {
1190 // File without newline at the end
1191 break;
1109 } 1192 }
1110 } 1193 }
1111 } else {
1112 warning("Error opening file %s due to %s", path, strerror(errno));
1113 } 1194 }
1114 } else if (warnStatFailure) { 1195 FREE_C_HEAP_ARRAY(char, buffer, mtInternal);
1115 warning("Could not stat file %s due to %s", path, strerror(errno)); 1196 } else {
1116 } 1197 warning("Error opening file %s due to %s", path, strerror(errno));
1198 }
1199 } else if (warnStatFailure) {
1200 warning("Could not stat file %s due to %s", path, strerror(errno));
1201 }
1117 } 1202 }
1118 1203
1119 class ServiceParseClosure : public ParseClosure { 1204 class ServiceParseClosure : public ParseClosure {
1120 GrowableArray<char*> _implNames; 1205 GrowableArray<char*> _implNames;
1121 public: 1206 public:
1122 ServiceParseClosure() : _implNames() {} 1207 ServiceParseClosure() : _implNames() {}
1123 void do_line(char* line) { 1208 void do_line(char* line) {
1209 size_t lineLen = strlen(line);
1210 char* implName = NEW_C_HEAP_ARRAY(char, lineLen + 1, mtCompiler); // TODO (gd) i'm leaking
1124 // Turn all '.'s into '/'s 1211 // Turn all '.'s into '/'s
1125 for (size_t index = 0; line[index] != '\0'; index++) { 1212 for (size_t index = 0; index < lineLen; ++index) {
1126 if (line[index] == '.') { 1213 if (line[index] == '.') {
1127 line[index] = '/'; 1214 implName[index] = '/';
1215 } else {
1216 implName[index] = line[index];
1128 } 1217 }
1129 } 1218 }
1130 _implNames.append(line); 1219 implName[lineLen] = '\0';
1220 _implNames.append(implName);
1131 } 1221 }
1132 GrowableArray<char*>* implNames() {return &_implNames;} 1222 GrowableArray<char*>* implNames() {return &_implNames;}
1133 }; 1223 };
1134 1224
1135 1225
1139 size_t path_len = strlen(home) + strlen("/lib/graal/services/") + strlen(serviceName) + 1; 1229 size_t path_len = strlen(home) + strlen("/lib/graal/services/") + strlen(serviceName) + 1;
1140 char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len); 1230 char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len);
1141 char sep = os::file_separator()[0]; 1231 char sep = os::file_separator()[0];
1142 sprintf(path, "%s%clib%cgraal%cservices%c%s", home, sep, sep, sep, sep, serviceName); 1232 sprintf(path, "%s%clib%cgraal%cservices%c%s", home, sep, sep, sep, sep, serviceName);
1143 ServiceParseClosure closure; 1233 ServiceParseClosure closure;
1144 parse_lines(path, &closure, true, THREAD); 1234 parse_lines(path, &closure, true); // TODO(gd) cache parsing results?
1145 1235
1146 GrowableArray<char*>* implNames = closure.implNames(); 1236 GrowableArray<char*>* implNames = closure.implNames();
1147 objArrayOop servicesOop = oopFactory::new_objArray(serviceKlass(), implNames->length(), CHECK_NH); 1237 objArrayOop servicesOop = oopFactory::new_objArray(serviceKlass(), implNames->length(), CHECK_NH);
1148 objArrayHandle services(THREAD, servicesOop); 1238 objArrayHandle services(THREAD, servicesOop);
1149 for (int i = 0; i < implNames->length(); ++i) { 1239 for (int i = 0; i < implNames->length(); ++i) {
1151 Handle service = create_Service(implName, CHECK_NH); 1241 Handle service = create_Service(implName, CHECK_NH);
1152 services->obj_at_put(i, service()); 1242 services->obj_at_put(i, service());
1153 } 1243 }
1154 return services; 1244 return services;
1155 } 1245 }
1156
1157 #include "graalRuntime.inline.hpp"