comparison src/share/vm/graal/graalRuntime.cpp @ 21525:fad971028755

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 28 May 2015 21:26:54 +0200
parents 923c37b10fb4 cecb4e39521c
children
comparison
equal deleted inserted replaced
21524:54933d47cfa4 21525:fad971028755
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 void HotSpotOptions.parseVMOptions()
729 JVM_ENTRY(void, JVM_ParseGraalOptions(JNIEnv *env, jclass c))
730 HandleMark hm;
731 KlassHandle hotSpotOptionsClass(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(c)));
732 GraalRuntime::parse_arguments(hotSpotOptionsClass, CHECK);
733 JVM_END
734
735 716
736 void GraalRuntime::ensure_graal_class_loader_is_initialized() { 717 void GraalRuntime::ensure_graal_class_loader_is_initialized() {
737 // 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.
738 // 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
739 // guaranteed to have been initialized. By going through the static 720 // guaranteed to have been initialized. By going through the static
769 InstanceKlass* ik = InstanceKlass::cast(klass()); 750 InstanceKlass* ik = InstanceKlass::cast(klass());
770 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());
771 *((jboolean *) addr) = (jboolean) UseGraalClassLoader; 752 *((jboolean *) addr) = (jboolean) UseGraalClassLoader;
772 klass->initialize(CHECK_ABORT); 753 klass->initialize(CHECK_ABORT);
773 _FactoryKlass = klass(); 754 _FactoryKlass = klass();
774 } 755 assert(!UseGraalClassLoader || SystemDictionary::graal_loader() != NULL, "Graal classloader should have been initialized");
775 } 756 }
776 757 }
777 jint GraalRuntime::check_arguments(TRAPS) { 758
778 KlassHandle nullHandle; 759 OptionsValueTable* GraalRuntime::parse_arguments() {
779 parse_arguments(nullHandle, THREAD); 760 OptionsTable* table = OptionsTable::load_options();
780 if (HAS_PENDING_EXCEPTION) { 761 if (table == NULL) {
781 // Errors in parsing Graal arguments cause exceptions. 762 return NULL;
782 // We now load and initialize HotSpotOptions which in turn 763 }
783 // causes argument parsing to be redone with better error messages. 764
784 CLEAR_PENDING_EXCEPTION; 765 OptionsValueTable* options = new OptionsValueTable(table);
785 TempNewSymbol name = SymbolTable::new_symbol("Lcom/oracle/graal/hotspot/HotSpotOptions;", CHECK_ABORT_(JNI_ERR));
786 instanceKlassHandle hotSpotOptionsClass = resolve_or_fail(name, CHECK_ABORT_(JNI_ERR));
787
788 parse_arguments(hotSpotOptionsClass, THREAD);
789 assert(HAS_PENDING_EXCEPTION, "must be");
790
791 ResourceMark rm;
792 Handle exception = PENDING_EXCEPTION;
793 CLEAR_PENDING_EXCEPTION;
794 oop message = java_lang_Throwable::message(exception);
795 if (message != NULL) {
796 tty->print_cr("Error parsing Graal options: %s", java_lang_String::as_utf8_string(message));
797 } else {
798 call_printStackTrace(exception, THREAD);
799 }
800 return JNI_ERR;
801 }
802 return JNI_OK;
803 }
804
805 void GraalRuntime::parse_arguments(KlassHandle hotSpotOptionsClass, TRAPS) {
806 ResourceMark rm(THREAD);
807 766
808 // Process option overrides from graal.options first 767 // Process option overrides from graal.options first
809 parse_graal_options_file(hotSpotOptionsClass, CHECK); 768 parse_graal_options_file(options);
810 769
811 // Now process options on the command line 770 // Now process options on the command line
812 int numOptions = Arguments::num_graal_args(); 771 int numOptions = Arguments::num_graal_args();
813 for (int i = 0; i < numOptions; i++) { 772 for (int i = 0; i < numOptions; i++) {
814 char* arg = Arguments::graal_args_array()[i]; 773 char* arg = Arguments::graal_args_array()[i];
815 parse_argument(hotSpotOptionsClass, arg, CHECK); 774 if (!parse_argument(options, arg)) {
816 } 775 delete options;
817 } 776 return NULL;
818 777 }
819 void GraalRuntime::check_required_value(const char* name, size_t name_len, const char* value, TRAPS) { 778 }
820 if (value == NULL) { 779 return options;
821 char buf[200]; 780 }
822 jio_snprintf(buf, sizeof(buf), "Must use '-G:%.*s=<value>' format for %.*s option", name_len, name, name_len, name); 781
823 THROW_MSG(vmSymbols::java_lang_InternalError(), buf); 782 void not_found(OptionsTable* table, const char* argname, size_t namelen) {
824 } 783 jio_fprintf(defaultStream::error_stream(),"Unrecognized VM option '%.*s'\n", namelen, argname);
825 } 784 OptionDesc* fuzzy_matched = table->fuzzy_match(argname, strlen(argname));
826 785 if (fuzzy_matched != NULL) {
827 void GraalRuntime::parse_argument(KlassHandle hotSpotOptionsClass, char* arg, TRAPS) { 786 jio_fprintf(defaultStream::error_stream(),
828 ensure_graal_class_loader_is_initialized(); 787 "Did you mean '%s%s%s'?\n",
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();
829 char first = arg[0]; 796 char first = arg[0];
830 char* name; 797 const char* name;
831 size_t name_len; 798 size_t name_len;
832 bool recognized = true;
833 if (first == '+' || first == '-') { 799 if (first == '+' || first == '-') {
834 name = arg + 1; 800 name = arg + 1;
835 name_len = strlen(name); 801 OptionDesc* optionDesc = table->get(name);
836 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;
837 } else { 815 } else {
838 char* sep = strchr(arg, '='); 816 const char* sep = strchr(arg, '=');
839 name = arg; 817 name = arg;
840 char* value = NULL; 818 const char* value = NULL;
841 if (sep != NULL) { 819 if (sep != NULL) {
842 name_len = sep - name; 820 name_len = sep - name;
843 value = sep + 1; 821 value = sep + 1;
844 } else { 822 } else {
845 name_len = strlen(name); 823 name_len = strlen(name);
846 } 824 }
847 recognized = set_option(hotSpotOptionsClass, name, name_len, value, CHECK); 825 OptionDesc* optionDesc = table->get(name, name_len);
848 } 826 if (optionDesc == NULL) {
849 827 not_found(table, name, name_len);
850 if (!recognized) { 828 return false;
851 bool throw_err = hotSpotOptionsClass.is_null(); 829 }
852 if (!hotSpotOptionsClass.is_null()) { 830 if (optionDesc->type == _boolean) {
853 set_option_helper(hotSpotOptionsClass, name, name_len, Handle(), ' ', Handle(), 0L); 831 jio_fprintf(defaultStream::error_stream(), "Missing +/- setting for VM option '%s'\n", name);
854 if (!HAS_PENDING_EXCEPTION) { 832 return false;
855 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;
856 } 851 }
857 } 852 case _long: {
858 853 long long int long_value = ::strtoll(value, &check, 10);
859 if (throw_err) { 854 if (*check != '\0' || errno == ERANGE || long_value > max_jlong || long_value < min_jlong) {
860 char buf[200]; 855 jio_fprintf(defaultStream::error_stream(), "Expected long value for VM option '%s'\n", name);
861 jio_snprintf(buf, sizeof(buf), "Unrecognized Graal option %.*s", name_len, name); 856 return false;
862 THROW_MSG(vmSymbols::java_lang_InternalError(), buf); 857 }
863 } 858 optionValue.long_value = long_value;
864 } 859 break;
865 } 860 }
866 861 case _float: {
867 void GraalRuntime::parse_graal_options_file(KlassHandle hotSpotOptionsClass, TRAPS) { 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;
888 }
889 }
890
891 class GraalOptionParseClosure : public ParseClosure {
892 OptionsValueTable* _options;
893 public:
894 GraalOptionParseClosure(OptionsValueTable* options) : _options(options) {}
895 void do_line(char* line) {
896 if (!GraalRuntime::parse_argument(_options, line)) {
897 warn("There was an error parsing an argument. Skipping it.");
898 }
899 }
900 };
901
902 void GraalRuntime::parse_graal_options_file(OptionsValueTable* options) {
868 const char* home = Arguments::get_java_home(); 903 const char* home = Arguments::get_java_home();
869 size_t path_len = strlen(home) + strlen("/lib/graal.options") + 1; 904 size_t path_len = strlen(home) + strlen("/lib/graal.options") + 1;
870 char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len); 905 char path[JVM_MAXPATHLEN];
871 char sep = os::file_separator()[0]; 906 char sep = os::file_separator()[0];
872 sprintf(path, "%s%clib%cgraal.options", home, sep, sep); 907 jio_snprintf(path, JVM_MAXPATHLEN, "%s%clib%cgraal.options", home, sep, sep);
873 908 GraalOptionParseClosure closure(options);
874 struct stat st; 909 parse_lines(path, &closure, false);
875 if (os::stat(path, &st) == 0) { 910 }
876 int file_handle = os::open(path, 0, 0); 911
877 if (file_handle != -1) { 912 #define CHECK_WARN_ABORT_(message) THREAD); \
878 char* buffer = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, st.st_size); 913 if (HAS_PENDING_EXCEPTION) { \
879 int num_read = (int) os::read(file_handle, (char*) buffer, st.st_size); 914 warning(message); \
880 if (num_read == -1) { 915 char buf[512]; \
881 warning("Error reading file %s due to %s", path, strerror(errno)); 916 jio_snprintf(buf, 512, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
882 } else if (num_read != st.st_size) { 917 GraalRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \
883 warning("Only read %d of " SIZE_FORMAT " bytes from %s", num_read, (size_t) st.st_size, path); 918 return; \
919 } \
920 (void)(0
921
922 class SetOptionClosure : public ValueClosure<OptionValue> {
923 Thread* _thread;
924 public:
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] = '/';
884 } 942 }
885 os::close(file_handle); 943 }
886 if (num_read == st.st_size) { 944 fieldSig[fieldSigLen] = '\0';
887 char* line = buffer; 945 size_t declaringClassLen = strlen(declaringClass);
888 int lineNo = 1; 946 char* declaringClassBinary = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, declaringClassLen + 1);
889 while (line - buffer < num_read) { 947 for (size_t i = 0; i < declaringClassLen; ++i) {
890 char* nl = strchr(line, '\n'); 948 if (declaringClass[i] == '.') {
891 if (nl != NULL) { 949 declaringClassBinary[i] = '/';
892 *nl = '\0'; 950 } else {
893 } 951 declaringClassBinary[i] = declaringClass[i];
894 parse_argument(hotSpotOptionsClass, line, THREAD);
895 if (HAS_PENDING_EXCEPTION) {
896 warning("Error in %s:%d", path, lineNo);
897 return;
898 }
899 if (nl != NULL) {
900 line = nl + 1;
901 lineNo++;
902 } else {
903 // File without newline at the end
904 break;
905 }
906 }
907 } 952 }
908 } else { 953 }
909 warning("Error opening file %s due to %s", path, strerror(errno)); 954 declaringClassBinary[declaringClassLen] = '\0';
910 } 955
911 } 956 TempNewSymbol name = SymbolTable::new_symbol(declaringClassBinary, CHECK_WARN_ABORT_("Declaring class could not be found"));
912 } 957 Klass* klass = GraalRuntime::resolve_or_null(name, CHECK_WARN_ABORT_("Declaring class could not be resolved"));
913 958
914 jlong GraalRuntime::parse_primitive_option_value(char spec, const char* name, size_t name_len, const char* value, TRAPS) { 959 if (klass == NULL) {
915 check_required_value(name, name_len, value, CHECK_(0L)); 960 warning("Declaring class for option %s could not be resolved", declaringClass);
916 union { 961 abort();
917 jint i; 962 return;
918 jlong l; 963 }
919 double d; 964
920 } uu; 965 // The class has been loaded so the field and signature should already be in the symbol
921 uu.l = 0L; 966 // table. If they're not there, the field doesn't exist.
922 char dummy; 967 TempNewSymbol fieldname = SymbolTable::probe(fieldName, (int)strlen(fieldName));
923 switch (spec) { 968 TempNewSymbol signame = SymbolTable::probe(fieldSig, (int)fieldSigLen);
924 case 'd': 969 if (fieldname == NULL || signame == NULL) {
925 case 'f': { 970 warning("Symbols for field for option %s not found (in %s)", fieldName, declaringClass);
926 if (sscanf(value, "%lf%c", &uu.d, &dummy) == 1) { 971 abort();
927 return uu.l; 972 return;
928 } 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);
929 break; 989 break;
930 } 990 }
931 case 'i': { 991 case _int: {
932 if (sscanf(value, "%d%c", &uu.i, &dummy) == 1) { 992 jvalue jv;
933 return (jlong)uu.i; 993 jv.i = optionValue->int_value;
934 } 994 value = java_lang_boxing_object::create(T_INT, &jv, THREAD);
935 break; 995 break;
936 } 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;
937 default: 1018 default:
938 ShouldNotReachHere(); 1019 ShouldNotReachHere();
939 } 1020 }
940 ResourceMark rm(THREAD); 1021
941 char buf[200]; 1022 oop optionValueOop = klass->java_mirror()->obj_field(fd.offset());
942 bool missing = strlen(value) == 0; 1023
943 if (missing) { 1024 if (optionValueOop == NULL) {
944 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);
945 } else { 1026 abort();
946 jio_snprintf(buf, sizeof(buf), "Invalid %s value for Graal option %.*s: %s", (spec == 'i' ? "numeric" : "float/double"), name_len, name, value); 1027 return;
947 } 1028 }
948 THROW_MSG_(vmSymbols::java_lang_InternalError(), buf, 0L); 1029
949 } 1030 if (!InstanceKlass::cast(optionValueOop->klass())->find_field(vmSymbols::value_name(), vmSymbols::object_signature(), false, &fd)) {
950 1031 warning("'Object value' field not found in option class %s, can not set option %s", fieldClass, fieldName);
951 void GraalRuntime::set_option_helper(KlassHandle hotSpotOptionsClass, char* name, size_t name_len, Handle option, jchar spec, Handle stringValue, jlong primitiveValue) { 1032 abort();
952 Thread* THREAD = Thread::current(); 1033 return;
953 Handle name_handle; 1034 }
954 if (name != NULL) { 1035
955 if (strlen(name) > name_len) { 1036 optionValueOop->obj_field_put(fd.offset(), value);
956 // Temporarily replace '=' with NULL to create the Java string for the option name 1037 }
957 char save = name[name_len]; 1038 };
958 name[name_len] = '\0'; 1039
959 name_handle = java_lang_String::create_from_str(name, THREAD); 1040 void GraalRuntime::set_options(OptionsValueTable* options, TRAPS) {
960 name[name_len] = '='; 1041 ensure_graal_class_loader_is_initialized();
961 if (HAS_PENDING_EXCEPTION) { 1042 {
962 return; 1043 ResourceMark rm;
963 } 1044 SetOptionClosure closure(THREAD);
964 } else { 1045 options->for_each(&closure);
965 assert(strlen(name) == name_len, "must be"); 1046 if (closure.is_aborted()) {
966 name_handle = java_lang_String::create_from_str(name, CHECK); 1047 vm_abort(false);
967 } 1048 }
968 } 1049 }
969 1050 OptionValue* printFlags = options->get(PRINT_FLAGS_ARG);
970 TempNewSymbol setOption = SymbolTable::new_symbol("setOption", CHECK); 1051 if (printFlags != NULL && printFlags->boolean_value) {
971 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);
972 JavaValue result(T_VOID); 1062 JavaValue result(T_VOID);
973 JavaCallArguments args; 1063 JavaCallArguments args;
974 args.push_oop(name_handle()); 1064 JavaCalls::call_static(&result, hotSpotOptionsClass, setOption, vmSymbols::void_method_signature(), &args, CHECK);
975 args.push_oop(option());
976 args.push_int(spec);
977 args.push_oop(stringValue());
978 args.push_long(primitiveValue);
979 JavaCalls::call_static(&result, hotSpotOptionsClass, setOption, sig, &args, CHECK);
980 }
981
982 Handle GraalRuntime::get_OptionValue(const char* declaringClass, const char* fieldName, const char* fieldSig, TRAPS) {
983 TempNewSymbol name = SymbolTable::new_symbol(declaringClass, CHECK_NH);
984 Klass* klass = resolve_or_fail(name, CHECK_NH);
985
986 // The class has been loaded so the field and signature should already be in the symbol
987 // table. If they're not there, the field doesn't exist.
988 TempNewSymbol fieldname = SymbolTable::probe(fieldName, (int)strlen(fieldName));
989 TempNewSymbol signame = SymbolTable::probe(fieldSig, (int)strlen(fieldSig));
990 if (fieldname == NULL || signame == NULL) {
991 THROW_MSG_(vmSymbols::java_lang_NoSuchFieldError(), (char*) fieldName, Handle());
992 }
993 // Make sure class is initialized before handing id's out to fields
994 klass->initialize(CHECK_NH);
995
996 fieldDescriptor fd;
997 if (!InstanceKlass::cast(klass)->find_field(fieldname, signame, true, &fd)) {
998 THROW_MSG_(vmSymbols::java_lang_NoSuchFieldError(), (char*) fieldName, Handle());
999 }
1000
1001 Handle ret = klass->java_mirror()->obj_field(fd.offset());
1002 return ret;
1003 } 1065 }
1004 1066
1005 Handle GraalRuntime::create_Service(const char* name, TRAPS) { 1067 Handle GraalRuntime::create_Service(const char* name, TRAPS) {
1006 TempNewSymbol kname = SymbolTable::new_symbol(name, CHECK_NH); 1068 TempNewSymbol kname = SymbolTable::new_symbol(name, CHECK_NH);
1007 Klass* k = resolve_or_fail(kname, CHECK_NH); 1069 Klass* k = resolve_or_fail(kname, CHECK_NH);
1072 vm_abort(false); 1134 vm_abort(false);
1073 } 1135 }
1074 return klass; 1136 return klass;
1075 } 1137 }
1076 1138
1077 Handle GraalRuntime::get_service_impls(KlassHandle serviceKlass, TRAPS) { 1139 void GraalRuntime::parse_lines(char* path, ParseClosure* closure, bool warnStatFailure) {
1078 const char* home = Arguments::get_java_home();
1079 const char* serviceName = serviceKlass->external_name();
1080 size_t path_len = strlen(home) + strlen("/lib/graal/services/") + strlen(serviceName) + 1;
1081 char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len);
1082 char sep = os::file_separator()[0];
1083 sprintf(path, "%s%clib%cgraal%cservices%c%s", home, sep, sep, sep, sep, serviceName);
1084 struct stat st; 1140 struct stat st;
1085 if (os::stat(path, &st) == 0) { 1141 if (os::stat(path, &st) == 0 && (st.st_mode & S_IFREG) == S_IFREG) { // exists & is regular file
1086 int file_handle = os::open(path, 0, 0); 1142 int file_handle = os::open(path, 0, 0);
1087 if (file_handle != -1) { 1143 if (file_handle != -1) {
1088 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);
1089 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);
1090 if (num_read == -1) { 1146 if (num_read == -1) {
1091 warning("Error reading file %s due to %s", path, strerror(errno)); 1147 warning("Error reading file %s due to %s", path, strerror(errno));
1092 } else if (num_read != st.st_size) { 1148 } else if (num_read != st.st_size) {
1093 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);
1094 } 1150 }
1095 os::close(file_handle); 1151 os::close(file_handle);
1152 closure->set_filename(path);
1096 if (num_read == st.st_size) { 1153 if (num_read == st.st_size) {
1097 buffer[num_read] = '\0'; 1154 buffer[num_read] = '\0';
1098 GrowableArray<char*>* implNames = new GrowableArray<char*>(); 1155
1099 char* line = buffer; 1156 char* line = buffer;
1100 while (line - buffer < num_read) { 1157 while (line - buffer < num_read && !closure->is_aborted()) {
1101 // find line end (\r, \n or \r\n) 1158 // find line end (\r, \n or \r\n)
1102 char* nextline = NULL; 1159 char* nextline = NULL;
1103 char* cr = strchr(line, '\r'); 1160 char* cr = strchr(line, '\r');
1104 char* lf = strchr(line, '\n'); 1161 char* lf = strchr(line, '\n');
1105 if (cr != NULL && lf != NULL) { 1162 if (cr != NULL && lf != NULL) {
1123 // trim right 1180 // trim right
1124 while (end > line && (*(end -1) == ' ' || *(end -1) == '\t')) end--; 1181 while (end > line && (*(end -1) == ' ' || *(end -1) == '\t')) end--;
1125 *end = '\0'; 1182 *end = '\0';
1126 // skip comments and empty lines 1183 // skip comments and empty lines
1127 if (*line != '#' && strlen(line) > 0) { 1184 if (*line != '#' && strlen(line) > 0) {
1128 // Turn all '.'s into '/'s 1185 closure->parse_line(line);
1129 for (size_t index = 0; line[index] != '\0'; index++) {
1130 if (line[index] == '.') {
1131 line[index] = '/';
1132 }
1133 }
1134 implNames->append(line);
1135 } 1186 }
1136 if (nextline != NULL) { 1187 if (nextline != NULL) {
1137 line = nextline; 1188 line = nextline;
1138 } else { 1189 } else {
1139 // File without newline at the end 1190 // File without newline at the end
1140 break; 1191 break;
1141 } 1192 }
1142 } 1193 }
1143
1144 objArrayOop servicesOop = oopFactory::new_objArray(serviceKlass(), implNames->length(), CHECK_NH);
1145 objArrayHandle services(THREAD, servicesOop);
1146 for (int i = 0; i < implNames->length(); ++i) {
1147 char* implName = implNames->at(i);
1148 Handle service = create_Service(implName, CHECK_NH);
1149 services->obj_at_put(i, service());
1150 }
1151 return services;
1152 } 1194 }
1195 FREE_C_HEAP_ARRAY(char, buffer, mtInternal);
1153 } else { 1196 } else {
1154 warning("Error opening file %s due to %s", path, strerror(errno)); 1197 warning("Error opening file %s due to %s", path, strerror(errno));
1155 } 1198 }
1156 } else { 1199 } else if (warnStatFailure) {
1157 warning("Error opening file %s due to %s", path, strerror(errno)); 1200 warning("Could not stat file %s due to %s", path, strerror(errno));
1158 } 1201 }
1159 return Handle(); 1202 }
1160 } 1203
1161 1204 class ServiceParseClosure : public ParseClosure {
1162 #include "graalRuntime.inline.hpp" 1205 GrowableArray<char*> _implNames;
1206 public:
1207 ServiceParseClosure() : _implNames() {}
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
1211 // Turn all '.'s into '/'s
1212 for (size_t index = 0; index < lineLen; ++index) {
1213 if (line[index] == '.') {
1214 implName[index] = '/';
1215 } else {
1216 implName[index] = line[index];
1217 }
1218 }
1219 implName[lineLen] = '\0';
1220 _implNames.append(implName);
1221 }
1222 GrowableArray<char*>* implNames() {return &_implNames;}
1223 };
1224
1225
1226 Handle GraalRuntime::get_service_impls(KlassHandle serviceKlass, TRAPS) {
1227 const char* home = Arguments::get_java_home();
1228 const char* serviceName = serviceKlass->external_name();
1229 size_t path_len = strlen(home) + strlen("/lib/graal/services/") + strlen(serviceName) + 1;
1230 char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len);
1231 char sep = os::file_separator()[0];
1232 sprintf(path, "%s%clib%cgraal%cservices%c%s", home, sep, sep, sep, sep, serviceName);
1233 ServiceParseClosure closure;
1234 parse_lines(path, &closure, true); // TODO(gd) cache parsing results?
1235
1236 GrowableArray<char*>* implNames = closure.implNames();
1237 objArrayOop servicesOop = oopFactory::new_objArray(serviceKlass(), implNames->length(), CHECK_NH);
1238 objArrayHandle services(THREAD, servicesOop);
1239 for (int i = 0; i < implNames->length(); ++i) {
1240 char* implName = implNames->at(i);
1241 Handle service = create_Service(implName, CHECK_NH);
1242 services->obj_at_put(i, service());
1243 }
1244 return services;
1245 }