Mercurial > hg > truffle
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" |