Mercurial > hg > truffle
comparison src/share/vm/memory/universe.cpp @ 12056:740e263c80c6
8003424: Enable Class Data Sharing for CompressedOops
8016729: ObjectAlignmentInBytes=16 now forces the use of heap based compressed oops
8005933: The -Xshare:auto option is ignored for -server
Summary: Move klass metaspace above the heap and support CDS with compressed klass ptrs.
Reviewed-by: coleenp, kvn, mgerdin, tschatzl, stefank
author | hseigel |
---|---|
date | Thu, 15 Aug 2013 20:04:10 -0400 |
parents | 85147f28faba |
children | 58fc8e2b7b6d 1a8fb39bdbc4 |
comparison
equal
deleted
inserted
replaced
12055:d96f52012aaa | 12056:740e263c80c6 |
---|---|
143 | 143 |
144 NarrowPtrStruct Universe::_narrow_oop = { NULL, 0, true }; | 144 NarrowPtrStruct Universe::_narrow_oop = { NULL, 0, true }; |
145 NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true }; | 145 NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true }; |
146 address Universe::_narrow_ptrs_base; | 146 address Universe::_narrow_ptrs_base; |
147 | 147 |
148 size_t Universe::_class_metaspace_size; | |
149 | |
150 void Universe::basic_type_classes_do(void f(Klass*)) { | 148 void Universe::basic_type_classes_do(void f(Klass*)) { |
151 f(boolArrayKlassObj()); | 149 f(boolArrayKlassObj()); |
152 f(byteArrayKlassObj()); | 150 f(byteArrayKlassObj()); |
153 f(charArrayKlassObj()); | 151 f(charArrayKlassObj()); |
154 f(intArrayKlassObj()); | 152 f(intArrayKlassObj()); |
639 jint status = Universe::initialize_heap(); | 637 jint status = Universe::initialize_heap(); |
640 if (status != JNI_OK) { | 638 if (status != JNI_OK) { |
641 return status; | 639 return status; |
642 } | 640 } |
643 | 641 |
642 Metaspace::global_initialize(); | |
643 | |
644 // Create memory for metadata. Must be after initializing heap for | 644 // Create memory for metadata. Must be after initializing heap for |
645 // DumpSharedSpaces. | 645 // DumpSharedSpaces. |
646 ClassLoaderData::init_null_class_loader_data(); | 646 ClassLoaderData::init_null_class_loader_data(); |
647 | 647 |
648 // We have a heap so create the Method* caches before | 648 // We have a heap so create the Method* caches before |
691 const size_t total_size = heap_size + HeapBaseMinAddress; | 691 const size_t total_size = heap_size + HeapBaseMinAddress; |
692 // Return specified base for the first request. | 692 // Return specified base for the first request. |
693 if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) { | 693 if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) { |
694 base = HeapBaseMinAddress; | 694 base = HeapBaseMinAddress; |
695 | 695 |
696 // If the total size and the metaspace size are small enough to allow | 696 // If the total size is small enough to allow UnscaledNarrowOop then |
697 // UnscaledNarrowOop then just use UnscaledNarrowOop. | 697 // just use UnscaledNarrowOop. |
698 } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop) && | 698 } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop)) { |
699 (!UseCompressedKlassPointers || | |
700 (((OopEncodingHeapMax - heap_size) + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax))) { | |
701 // We don't need to check the metaspace size here because it is always smaller | |
702 // than total_size. | |
703 if ((total_size <= NarrowOopHeapMax) && (mode == UnscaledNarrowOop) && | 699 if ((total_size <= NarrowOopHeapMax) && (mode == UnscaledNarrowOop) && |
704 (Universe::narrow_oop_shift() == 0)) { | 700 (Universe::narrow_oop_shift() == 0)) { |
705 // Use 32-bits oops without encoding and | 701 // Use 32-bits oops without encoding and |
706 // place heap's top on the 4Gb boundary | 702 // place heap's top on the 4Gb boundary |
707 base = (NarrowOopHeapMax - heap_size); | 703 base = (NarrowOopHeapMax - heap_size); |
714 // place heap's top on the 32Gb boundary in case | 710 // place heap's top on the 32Gb boundary in case |
715 // total_size > 4Gb or failed to reserve below 4Gb. | 711 // total_size > 4Gb or failed to reserve below 4Gb. |
716 base = (OopEncodingHeapMax - heap_size); | 712 base = (OopEncodingHeapMax - heap_size); |
717 } | 713 } |
718 } | 714 } |
719 | |
720 // See if ZeroBaseNarrowOop encoding will work for a heap based at | |
721 // (KlassEncodingMetaspaceMax - class_metaspace_size()). | |
722 } else if (UseCompressedKlassPointers && (mode != HeapBasedNarrowOop) && | |
723 (Universe::class_metaspace_size() + HeapBaseMinAddress <= KlassEncodingMetaspaceMax) && | |
724 (KlassEncodingMetaspaceMax + heap_size - Universe::class_metaspace_size() <= OopEncodingHeapMax)) { | |
725 base = (KlassEncodingMetaspaceMax - Universe::class_metaspace_size()); | |
726 } else { | 715 } else { |
727 // UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or | 716 // UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or |
728 // HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb. | 717 // HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb. |
729 Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); | 718 Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); |
730 } | 719 } |
731 | 720 |
732 // Set narrow_oop_base and narrow_oop_use_implicit_null_checks | 721 // Set narrow_oop_base and narrow_oop_use_implicit_null_checks |
733 // used in ReservedHeapSpace() constructors. | 722 // used in ReservedHeapSpace() constructors. |
734 // The final values will be set in initialize_heap() below. | 723 // The final values will be set in initialize_heap() below. |
735 if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax) && | 724 if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax)) { |
736 (!UseCompressedKlassPointers || (base + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax)) { | |
737 // Use zero based compressed oops | 725 // Use zero based compressed oops |
738 Universe::set_narrow_oop_base(NULL); | 726 Universe::set_narrow_oop_base(NULL); |
739 // Don't need guard page for implicit checks in indexed | 727 // Don't need guard page for implicit checks in indexed |
740 // addressing mode with zero based Compressed Oops. | 728 // addressing mode with zero based Compressed Oops. |
741 Universe::set_narrow_oop_use_implicit_null_checks(true); | 729 Universe::set_narrow_oop_use_implicit_null_checks(true); |
814 if (verbose) { | 802 if (verbose) { |
815 tty->cr(); | 803 tty->cr(); |
816 tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", | 804 tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", |
817 Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M); | 805 Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M); |
818 } | 806 } |
819 if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) || | 807 if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax)) { |
820 (UseCompressedKlassPointers && | |
821 ((uint64_t)Universe::heap()->base() + Universe::class_metaspace_size() > KlassEncodingMetaspaceMax))) { | |
822 // Can't reserve heap below 32Gb. | 808 // Can't reserve heap below 32Gb. |
823 // keep the Universe::narrow_oop_base() set in Universe::reserve_heap() | 809 // keep the Universe::narrow_oop_base() set in Universe::reserve_heap() |
824 Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); | 810 Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); |
825 if (verbose) { | 811 if (verbose) { |
826 tty->print(", %s: "PTR_FORMAT, | 812 tty->print(", %s: "PTR_FORMAT, |
847 if (verbose) { | 833 if (verbose) { |
848 tty->print(", %s", narrow_oop_mode_to_string(UnscaledNarrowOop)); | 834 tty->print(", %s", narrow_oop_mode_to_string(UnscaledNarrowOop)); |
849 } | 835 } |
850 } | 836 } |
851 } | 837 } |
838 | |
852 if (verbose) { | 839 if (verbose) { |
853 tty->cr(); | 840 tty->cr(); |
854 tty->cr(); | 841 tty->cr(); |
855 } | 842 } |
856 if (UseCompressedKlassPointers) { | |
857 Universe::set_narrow_klass_base(Universe::narrow_oop_base()); | |
858 Universe::set_narrow_klass_shift(MIN2(Universe::narrow_oop_shift(), LogKlassAlignmentInBytes)); | |
859 } | |
860 Universe::set_narrow_ptrs_base(Universe::narrow_oop_base()); | 843 Universe::set_narrow_ptrs_base(Universe::narrow_oop_base()); |
861 } | 844 } |
862 // Universe::narrow_oop_base() is one page below the metaspace | 845 // Universe::narrow_oop_base() is one page below the heap. |
863 // base. The actual metaspace base depends on alignment constraints | 846 assert((intptr_t)Universe::narrow_oop_base() <= (intptr_t)(Universe::heap()->base() - |
864 // so we don't know its exact location here. | 847 os::vm_page_size()) || |
865 assert((intptr_t)Universe::narrow_oop_base() <= (intptr_t)(Universe::heap()->base() - os::vm_page_size() - ClassMetaspaceSize) || | |
866 Universe::narrow_oop_base() == NULL, "invalid value"); | 848 Universe::narrow_oop_base() == NULL, "invalid value"); |
867 assert(Universe::narrow_oop_shift() == LogMinObjAlignmentInBytes || | 849 assert(Universe::narrow_oop_shift() == LogMinObjAlignmentInBytes || |
868 Universe::narrow_oop_shift() == 0, "invalid value"); | 850 Universe::narrow_oop_shift() == 0, "invalid value"); |
869 #endif | 851 #endif |
870 | 852 |
880 } | 862 } |
881 | 863 |
882 | 864 |
883 // Reserve the Java heap, which is now the same for all GCs. | 865 // Reserve the Java heap, which is now the same for all GCs. |
884 ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { | 866 ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { |
885 // Add in the class metaspace area so the classes in the headers can | 867 size_t total_reserved = align_size_up(heap_size, alignment); |
886 // be compressed the same as instances. | |
887 // Need to round class space size up because it's below the heap and | |
888 // the actual alignment depends on its size. | |
889 Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment)); | |
890 size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment); | |
891 assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())), | 868 assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())), |
892 "heap size is too big for compressed oops"); | 869 "heap size is too big for compressed oops"); |
893 char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); | 870 char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); |
894 | 871 |
895 ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr); | 872 ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr); |
921 if (!total_rs.is_reserved()) { | 898 if (!total_rs.is_reserved()) { |
922 vm_exit_during_initialization(err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", total_reserved/K)); | 899 vm_exit_during_initialization(err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", total_reserved/K)); |
923 return total_rs; | 900 return total_rs; |
924 } | 901 } |
925 | 902 |
926 // Split the reserved space into main Java heap and a space for | |
927 // classes so that they can be compressed using the same algorithm | |
928 // as compressed oops. If compress oops and compress klass ptrs are | |
929 // used we need the meta space first: if the alignment used for | |
930 // compressed oops is greater than the one used for compressed klass | |
931 // ptrs, a metadata space on top of the heap could become | |
932 // unreachable. | |
933 ReservedSpace class_rs = total_rs.first_part(Universe::class_metaspace_size()); | |
934 ReservedSpace heap_rs = total_rs.last_part(Universe::class_metaspace_size(), alignment); | |
935 Metaspace::initialize_class_space(class_rs); | |
936 | |
937 if (UseCompressedOops) { | 903 if (UseCompressedOops) { |
938 // Universe::initialize_heap() will reset this to NULL if unscaled | 904 // Universe::initialize_heap() will reset this to NULL if unscaled |
939 // or zero-based narrow oops are actually used. | 905 // or zero-based narrow oops are actually used. |
940 address base = (address)(total_rs.base() - os::vm_page_size()); | 906 address base = (address)(total_rs.base() - os::vm_page_size()); |
941 Universe::set_narrow_oop_base(base); | 907 Universe::set_narrow_oop_base(base); |
942 } | 908 } |
943 return heap_rs; | 909 return total_rs; |
944 } | 910 } |
945 | 911 |
946 | 912 |
947 // It's the caller's repsonsibility to ensure glitch-freedom | 913 // It's the caller's responsibility to ensure glitch-freedom |
948 // (if required). | 914 // (if required). |
949 void Universe::update_heap_info_at_gc() { | 915 void Universe::update_heap_info_at_gc() { |
950 _heap_capacity_at_last_gc = heap()->capacity(); | 916 _heap_capacity_at_last_gc = heap()->capacity(); |
951 _heap_used_at_last_gc = heap()->used(); | 917 _heap_used_at_last_gc = heap()->used(); |
952 } | 918 } |