49 #endif |
49 #endif |
50 |
50 |
51 jobject JVMCIRuntime::_HotSpotJVMCIRuntime_instance = NULL; |
51 jobject JVMCIRuntime::_HotSpotJVMCIRuntime_instance = NULL; |
52 bool JVMCIRuntime::_HotSpotJVMCIRuntime_initialized = false; |
52 bool JVMCIRuntime::_HotSpotJVMCIRuntime_initialized = false; |
53 bool JVMCIRuntime::_well_known_classes_initialized = false; |
53 bool JVMCIRuntime::_well_known_classes_initialized = false; |
54 const char* JVMCIRuntime::_compiler = NULL; |
|
55 int JVMCIRuntime::_trivial_prefixes_count = 0; |
54 int JVMCIRuntime::_trivial_prefixes_count = 0; |
56 char** JVMCIRuntime::_trivial_prefixes = NULL; |
55 char** JVMCIRuntime::_trivial_prefixes = NULL; |
57 bool JVMCIRuntime::_shutdown_called = false; |
56 bool JVMCIRuntime::_shutdown_called = false; |
58 |
57 |
59 BasicType JVMCIRuntime::kindToBasicType(Handle kind, TRAPS) { |
58 BasicType JVMCIRuntime::kindToBasicType(Handle kind, TRAPS) { |
639 Klass* k = SystemDictionary::resolve_or_null(name, CHECK); |
638 Klass* k = SystemDictionary::resolve_or_null(name, CHECK); |
640 instanceKlassHandle klass = InstanceKlass::cast(k); |
639 instanceKlassHandle klass = InstanceKlass::cast(k); |
641 assert(klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD), |
640 assert(klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD), |
642 "HotSpotJVMCIRuntime initialization should only be triggered through JVMCI initialization"); |
641 "HotSpotJVMCIRuntime initialization should only be triggered through JVMCI initialization"); |
643 #endif |
642 #endif |
644 |
|
645 if (_compiler != NULL) { |
|
646 JavaCallArguments args; |
|
647 oop compiler = java_lang_String::create_oop_from_str(_compiler, CHECK); |
|
648 args.push_oop(compiler); |
|
649 callStatic("jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig", |
|
650 "selectCompiler", |
|
651 "(Ljava/lang/String;)Ljava/lang/Boolean;", &args, CHECK); |
|
652 } |
|
653 |
643 |
654 Handle result = callStatic("jdk/vm/ci/hotspot/HotSpotJVMCIRuntime", |
644 Handle result = callStatic("jdk/vm/ci/hotspot/HotSpotJVMCIRuntime", |
655 "runtime", |
645 "runtime", |
656 "()Ljdk/vm/ci/hotspot/HotSpotJVMCIRuntime;", NULL, CHECK); |
646 "()Ljdk/vm/ci/hotspot/HotSpotJVMCIRuntime;", NULL, CHECK); |
657 objArrayOop trivial_prefixes = HotSpotJVMCIRuntime::trivialPrefixes(result); |
647 objArrayOop trivial_prefixes = HotSpotJVMCIRuntime::trivialPrefixes(result); |
781 ThreadToNativeFromVM trans(thread); |
771 ThreadToNativeFromVM trans(thread); |
782 env->RegisterNatives(c2vmClass, CompilerToVM::methods, CompilerToVM::methods_count()); |
772 env->RegisterNatives(c2vmClass, CompilerToVM::methods, CompilerToVM::methods_count()); |
783 } |
773 } |
784 JVM_END |
774 JVM_END |
785 |
775 |
786 /** |
|
787 * Closure for parsing a line from a *.properties file in jre/lib/jvmci/properties. |
|
788 * The line must match the regular expression "[^=]+=.*". That is one or more |
|
789 * characters other than '=' followed by '=' followed by zero or more characters. |
|
790 * Everything before the '=' is the property name and everything after '=' is the value. |
|
791 * Lines that start with '#' are treated as comments and ignored. |
|
792 * No special processing of whitespace or any escape characters is performed. |
|
793 * The last definition of a property "wins" (i.e., it overrides all earlier |
|
794 * definitions of the property). |
|
795 */ |
|
796 class JVMCIPropertiesFileClosure : public ParseClosure { |
|
797 SystemProperty** _plist; |
|
798 public: |
|
799 JVMCIPropertiesFileClosure(SystemProperty** plist) : _plist(plist) {} |
|
800 void do_line(char* line) { |
|
801 if (line[0] == '#') { |
|
802 // skip comment |
|
803 return; |
|
804 } |
|
805 size_t len = strlen(line); |
|
806 char* sep = strchr(line, '='); |
|
807 if (sep == NULL) { |
|
808 warn_and_abort("invalid format: could not find '=' character"); |
|
809 return; |
|
810 } |
|
811 if (sep == line) { |
|
812 warn_and_abort("invalid format: name cannot be empty"); |
|
813 return; |
|
814 } |
|
815 *sep = '\0'; |
|
816 const char* name = line; |
|
817 char* value = sep + 1; |
|
818 Arguments::PropertyList_unique_add(_plist, name, value); |
|
819 } |
|
820 }; |
|
821 |
|
822 void JVMCIRuntime::init_system_properties(SystemProperty** plist) { |
|
823 char jvmciDir[JVM_MAXPATHLEN]; |
|
824 const char* fileSep = os::file_separator(); |
|
825 jio_snprintf(jvmciDir, sizeof(jvmciDir), "%s%slib%sjvmci", |
|
826 Arguments::get_java_home(), fileSep, fileSep, fileSep); |
|
827 DIR* dir = os::opendir(jvmciDir); |
|
828 if (dir != NULL) { |
|
829 struct dirent *entry; |
|
830 char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(jvmciDir), mtInternal); |
|
831 JVMCIPropertiesFileClosure closure(plist); |
|
832 const unsigned suffix_len = (unsigned)strlen(".properties"); |
|
833 while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL && !closure.is_aborted()) { |
|
834 const char* name = entry->d_name; |
|
835 if (strlen(name) > suffix_len && strcmp(name + strlen(name) - suffix_len, ".properties") == 0) { |
|
836 char propertiesFilePath[JVM_MAXPATHLEN]; |
|
837 jio_snprintf(propertiesFilePath, sizeof(propertiesFilePath), "%s%s%s",jvmciDir, fileSep, name); |
|
838 JVMCIRuntime::parse_lines(propertiesFilePath, &closure, false); |
|
839 } |
|
840 } |
|
841 FREE_C_HEAP_ARRAY(char, dbuf); |
|
842 os::closedir(dir); |
|
843 } |
|
844 } |
|
845 |
|
846 #define CHECK_WARN_ABORT_(message) THREAD); \ |
776 #define CHECK_WARN_ABORT_(message) THREAD); \ |
847 if (HAS_PENDING_EXCEPTION) { \ |
777 if (HAS_PENDING_EXCEPTION) { \ |
848 warning(message); \ |
778 warning(message); \ |
849 char buf[512]; \ |
779 char buf[512]; \ |
850 jio_snprintf(buf, 512, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
780 jio_snprintf(buf, 512, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
851 JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \ |
781 JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \ |
852 return; \ |
782 return; \ |
853 } \ |
783 } \ |
854 (void)(0 |
784 (void)(0 |
855 |
785 |
856 void JVMCIRuntime::save_compiler(const char* compiler) { |
|
857 assert(compiler != NULL, "npe"); |
|
858 assert(_compiler == NULL, "cannot reassign JVMCI compiler"); |
|
859 _compiler = compiler; |
|
860 } |
|
861 |
|
862 void JVMCIRuntime::shutdown(TRAPS) { |
786 void JVMCIRuntime::shutdown(TRAPS) { |
863 if (_HotSpotJVMCIRuntime_instance != NULL) { |
787 if (_HotSpotJVMCIRuntime_instance != NULL) { |
864 _shutdown_called = true; |
788 _shutdown_called = true; |
865 HandleMark hm(THREAD); |
789 HandleMark hm(THREAD); |
866 Handle receiver = get_HotSpotJVMCIRuntime(CHECK); |
790 Handle receiver = get_HotSpotJVMCIRuntime(CHECK); |
882 } |
806 } |
883 } |
807 } |
884 } |
808 } |
885 return false; |
809 return false; |
886 } |
810 } |
887 |
|
888 void JVMCIRuntime::parse_lines(char* path, ParseClosure* closure, bool warnStatFailure) { |
|
889 struct stat st; |
|
890 if (::stat(path, &st) == 0 && (st.st_mode & S_IFREG) == S_IFREG) { // exists & is regular file |
|
891 int file_handle = ::open(path, os::default_file_open_flags(), 0); |
|
892 if (file_handle != -1) { |
|
893 char* buffer = NEW_C_HEAP_ARRAY(char, st.st_size + 1, mtInternal); |
|
894 int num_read; |
|
895 num_read = (int) ::read(file_handle, (char*) buffer, st.st_size); |
|
896 if (num_read == -1) { |
|
897 warning("Error reading file %s due to %s", path, strerror(errno)); |
|
898 } else if (num_read != st.st_size) { |
|
899 warning("Only read %d of " SIZE_FORMAT " bytes from %s", num_read, (size_t) st.st_size, path); |
|
900 } |
|
901 ::close(file_handle); |
|
902 closure->set_filename(path); |
|
903 if (num_read == st.st_size) { |
|
904 buffer[num_read] = '\0'; |
|
905 |
|
906 char* line = buffer; |
|
907 while (line - buffer < num_read && !closure->is_aborted()) { |
|
908 // find line end (\r, \n or \r\n) |
|
909 char* nextline = NULL; |
|
910 char* cr = strchr(line, '\r'); |
|
911 char* lf = strchr(line, '\n'); |
|
912 if (cr != NULL && lf != NULL) { |
|
913 char* min = MIN2(cr, lf); |
|
914 *min = '\0'; |
|
915 if (lf == cr + 1) { |
|
916 nextline = lf + 1; |
|
917 } else { |
|
918 nextline = min + 1; |
|
919 } |
|
920 } else if (cr != NULL) { |
|
921 *cr = '\0'; |
|
922 nextline = cr + 1; |
|
923 } else if (lf != NULL) { |
|
924 *lf = '\0'; |
|
925 nextline = lf + 1; |
|
926 } |
|
927 // trim left |
|
928 while (*line == ' ' || *line == '\t') line++; |
|
929 char* end = line + strlen(line); |
|
930 // trim right |
|
931 while (end > line && (*(end -1) == ' ' || *(end -1) == '\t')) end--; |
|
932 *end = '\0'; |
|
933 // skip comments and empty lines |
|
934 if (*line != '#' && strlen(line) > 0) { |
|
935 closure->parse_line(line); |
|
936 } |
|
937 if (nextline != NULL) { |
|
938 line = nextline; |
|
939 } else { |
|
940 // File without newline at the end |
|
941 break; |
|
942 } |
|
943 } |
|
944 } |
|
945 FREE_C_HEAP_ARRAY(char, buffer); |
|
946 } else { |
|
947 warning("Error opening file %s due to %s", path, strerror(errno)); |
|
948 } |
|
949 } else if (warnStatFailure) { |
|
950 warning("Could not stat file %s due to %s", path, strerror(errno)); |
|
951 } |
|
952 } |
|