561 void vm_shutdown_during_initialization(const char* error, const char* message) { |
561 void vm_shutdown_during_initialization(const char* error, const char* message) { |
562 vm_notify_during_shutdown(error, message); |
562 vm_notify_during_shutdown(error, message); |
563 vm_shutdown(); |
563 vm_shutdown(); |
564 } |
564 } |
565 |
565 |
566 jdk_version_info JDK_Version::_version_info = {0}; |
566 JDK_Version JDK_Version::_current; |
567 bool JDK_Version::_pre_jdk16_version = false; |
|
568 int JDK_Version::_jdk_version = 0; |
|
569 |
567 |
570 void JDK_Version::initialize() { |
568 void JDK_Version::initialize() { |
|
569 jdk_version_info info; |
|
570 assert(!_current.is_valid(), "Don't initialize twice"); |
|
571 |
571 void *lib_handle = os::native_java_library(); |
572 void *lib_handle = os::native_java_library(); |
572 jdk_version_info_fn_t func = |
573 jdk_version_info_fn_t func = CAST_TO_FN_PTR(jdk_version_info_fn_t, |
573 CAST_TO_FN_PTR(jdk_version_info_fn_t, hpi::dll_lookup(lib_handle, "JDK_GetVersionInfo0")); |
574 os::dll_lookup(lib_handle, "JDK_GetVersionInfo0")); |
574 |
575 |
575 if (func == NULL) { |
576 if (func == NULL) { |
576 // JDK older than 1.6 |
577 // JDK older than 1.6 |
577 _pre_jdk16_version = true; |
578 _current._partially_initialized = true; |
578 return; |
|
579 } |
|
580 |
|
581 if (func != NULL) { |
|
582 (*func)(&_version_info, sizeof(_version_info)); |
|
583 } |
|
584 if (jdk_major_version() == 1) { |
|
585 _jdk_version = jdk_minor_version(); |
|
586 } else { |
579 } else { |
587 // If the release version string is changed to n.x.x (e.g. 7.0.0) in a future release |
580 (*func)(&info, sizeof(info)); |
588 _jdk_version = jdk_major_version(); |
581 |
589 } |
582 int major = JDK_VERSION_MAJOR(info.jdk_version); |
|
583 int minor = JDK_VERSION_MINOR(info.jdk_version); |
|
584 int micro = JDK_VERSION_MICRO(info.jdk_version); |
|
585 int build = JDK_VERSION_BUILD(info.jdk_version); |
|
586 if (major == 1 && minor > 4) { |
|
587 // We represent "1.5.0" as "5.0", but 1.4.2 as itself. |
|
588 major = minor; |
|
589 minor = micro; |
|
590 micro = 0; |
|
591 } |
|
592 _current = JDK_Version(major, minor, micro, info.update_version, |
|
593 info.special_update_version, build, |
|
594 info.thread_park_blocker == 1); |
|
595 } |
|
596 } |
|
597 |
|
598 void JDK_Version::fully_initialize( |
|
599 uint8_t major, uint8_t minor, uint8_t micro, uint8_t update) { |
|
600 // This is only called when current is less than 1.6 and we've gotten |
|
601 // far enough in the initialization to determine the exact version. |
|
602 assert(major < 6, "not needed for JDK version >= 6"); |
|
603 assert(is_partially_initialized(), "must not initialize"); |
|
604 if (major < 5) { |
|
605 // JDK verison sequence: 1.2.x, 1.3.x, 1.4.x, 5.0.x, 6.0.x, etc. |
|
606 micro = minor; |
|
607 minor = major; |
|
608 major = 1; |
|
609 } |
|
610 _current = JDK_Version(major, minor, micro, update); |
590 } |
611 } |
591 |
612 |
592 void JDK_Version_init() { |
613 void JDK_Version_init() { |
593 JDK_Version::initialize(); |
614 JDK_Version::initialize(); |
594 } |
615 } |
|
616 |
|
617 static int64_t encode_jdk_version(const JDK_Version& v) { |
|
618 return |
|
619 ((int64_t)v.major_version() << (BitsPerByte * 5)) | |
|
620 ((int64_t)v.minor_version() << (BitsPerByte * 4)) | |
|
621 ((int64_t)v.micro_version() << (BitsPerByte * 3)) | |
|
622 ((int64_t)v.update_version() << (BitsPerByte * 2)) | |
|
623 ((int64_t)v.special_update_version() << (BitsPerByte * 1)) | |
|
624 ((int64_t)v.build_number() << (BitsPerByte * 0)); |
|
625 } |
|
626 |
|
627 int JDK_Version::compare(const JDK_Version& other) const { |
|
628 assert(is_valid() && other.is_valid(), "Invalid version (uninitialized?)"); |
|
629 if (!is_partially_initialized() && other.is_partially_initialized()) { |
|
630 return -(other.compare(*this)); // flip the comparators |
|
631 } |
|
632 assert(!other.is_partially_initialized(), "Not initialized yet"); |
|
633 if (is_partially_initialized()) { |
|
634 assert(other.major_version() >= 6, |
|
635 "Invalid JDK version comparison during initialization"); |
|
636 return -1; |
|
637 } else { |
|
638 uint64_t e = encode_jdk_version(*this); |
|
639 uint64_t o = encode_jdk_version(other); |
|
640 return (e > o) ? 1 : ((e == o) ? 0 : -1); |
|
641 } |
|
642 } |
|
643 |
|
644 void JDK_Version::to_string(char* buffer, size_t buflen) const { |
|
645 size_t index = 0; |
|
646 if (!is_valid()) { |
|
647 jio_snprintf(buffer, buflen, "%s", "(uninitialized)"); |
|
648 } else if (is_partially_initialized()) { |
|
649 jio_snprintf(buffer, buflen, "%s", "(uninitialized) pre-1.6.0"); |
|
650 } else { |
|
651 index += jio_snprintf( |
|
652 &buffer[index], buflen - index, "%d.%d", _major, _minor); |
|
653 if (_micro > 0) { |
|
654 index += jio_snprintf(&buffer[index], buflen - index, ".%d", _micro); |
|
655 } |
|
656 if (_update > 0) { |
|
657 index += jio_snprintf(&buffer[index], buflen - index, "_%02d", _update); |
|
658 } |
|
659 if (_special > 0) { |
|
660 index += jio_snprintf(&buffer[index], buflen - index, "%c", _special); |
|
661 } |
|
662 if (_build > 0) { |
|
663 index += jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build); |
|
664 } |
|
665 } |
|
666 } |