4678 |
4667 |
4679 void Metaspace::post_initialize() { |
4668 void Metaspace::post_initialize() { |
4680 MetaspaceGC::post_initialize(); |
4669 MetaspaceGC::post_initialize(); |
4681 } |
4670 } |
4682 |
4671 |
4683 void Metaspace::initialize_first_chunk(MetaspaceType type, MetadataType mdtype) { |
|
4684 Metachunk* chunk = get_initialization_chunk(type, mdtype); |
|
4685 if (chunk != NULL) { |
|
4686 // Add to this manager's list of chunks in use and current_chunk(). |
|
4687 get_space_manager(mdtype)->add_chunk(chunk, true); |
|
4688 } |
|
4689 } |
|
4690 |
|
4691 Metachunk* Metaspace::get_initialization_chunk(MetaspaceType type, MetadataType mdtype) { |
|
4692 size_t chunk_word_size = get_space_manager(mdtype)->get_initial_chunk_size(type); |
|
4693 |
|
4694 // Get a chunk from the chunk freelist |
|
4695 Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size); |
|
4696 |
|
4697 if (chunk == NULL) { |
|
4698 chunk = get_space_list(mdtype)->get_new_chunk(chunk_word_size, |
|
4699 get_space_manager(mdtype)->medium_chunk_bunch()); |
|
4700 } |
|
4701 |
|
4702 return chunk; |
|
4703 } |
|
4704 |
|
4705 void Metaspace::verify_global_initialization() { |
4672 void Metaspace::verify_global_initialization() { |
4706 assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized"); |
4673 assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized"); |
4707 assert(chunk_manager_metadata() != NULL, "Metadata ChunkManager has not been initialized"); |
4674 assert(chunk_manager_metadata() != NULL, "Metadata ChunkManager has not been initialized"); |
4708 |
4675 |
4709 if (using_class_space()) { |
4676 if (using_class_space()) { |
4710 assert(class_space_list() != NULL, "Class VirtualSpaceList has not been initialized"); |
4677 assert(class_space_list() != NULL, "Class VirtualSpaceList has not been initialized"); |
4711 assert(chunk_manager_class() != NULL, "Class ChunkManager has not been initialized"); |
4678 assert(chunk_manager_class() != NULL, "Class ChunkManager has not been initialized"); |
4712 } |
4679 } |
4713 } |
4680 } |
4714 |
4681 |
4715 void Metaspace::initialize(Mutex* lock, MetaspaceType type) { |
|
4716 verify_global_initialization(); |
|
4717 |
|
4718 // Allocate SpaceManager for metadata objects. |
|
4719 _vsm = new SpaceManager(NonClassType, type, lock); |
|
4720 |
|
4721 if (using_class_space()) { |
|
4722 // Allocate SpaceManager for classes. |
|
4723 _class_vsm = new SpaceManager(ClassType, type, lock); |
|
4724 } |
|
4725 |
|
4726 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); |
|
4727 |
|
4728 // Allocate chunk for metadata objects |
|
4729 initialize_first_chunk(type, NonClassType); |
|
4730 |
|
4731 // Allocate chunk for class metadata objects |
|
4732 if (using_class_space()) { |
|
4733 initialize_first_chunk(type, ClassType); |
|
4734 } |
|
4735 } |
|
4736 |
|
4737 size_t Metaspace::align_word_size_up(size_t word_size) { |
4682 size_t Metaspace::align_word_size_up(size_t word_size) { |
4738 size_t byte_size = word_size * wordSize; |
4683 size_t byte_size = word_size * wordSize; |
4739 return ReservedSpace::allocation_align_size_up(byte_size) / wordSize; |
4684 return ReservedSpace::allocation_align_size_up(byte_size) / wordSize; |
4740 } |
|
4741 |
|
4742 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { |
|
4743 assert(!_frozen, "sanity"); |
|
4744 // Don't use class_vsm() unless UseCompressedClassPointers is true. |
|
4745 if (is_class_space_allocation(mdtype)) { |
|
4746 return class_vsm()->allocate(word_size); |
|
4747 } else { |
|
4748 return vsm()->allocate(word_size); |
|
4749 } |
|
4750 } |
|
4751 |
|
4752 MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) { |
|
4753 assert(!_frozen, "sanity"); |
|
4754 size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord); |
|
4755 assert(delta_bytes > 0, "Must be"); |
|
4756 |
|
4757 size_t before = 0; |
|
4758 size_t after = 0; |
|
4759 MetaWord* res; |
|
4760 bool incremented; |
|
4761 |
|
4762 // Each thread increments the HWM at most once. Even if the thread fails to increment |
|
4763 // the HWM, an allocation is still attempted. This is because another thread must then |
|
4764 // have incremented the HWM and therefore the allocation might still succeed. |
|
4765 do { |
|
4766 incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before); |
|
4767 res = allocate(word_size, mdtype); |
|
4768 } while (!incremented && res == NULL); |
|
4769 |
|
4770 if (incremented) { |
|
4771 tracer()->report_gc_threshold(before, after, |
|
4772 MetaspaceGCThresholdUpdater::ExpandAndAllocate); |
|
4773 log_trace(gc, metaspace)("Increase capacity to GC from " SIZE_FORMAT " to " SIZE_FORMAT, before, after); |
|
4774 } |
|
4775 |
|
4776 return res; |
|
4777 } |
|
4778 |
|
4779 size_t Metaspace::used_words_slow(MetadataType mdtype) const { |
|
4780 if (mdtype == ClassType) { |
|
4781 return using_class_space() ? class_vsm()->sum_used_in_chunks_in_use() : 0; |
|
4782 } else { |
|
4783 return vsm()->sum_used_in_chunks_in_use(); // includes overhead! |
|
4784 } |
|
4785 } |
|
4786 |
|
4787 size_t Metaspace::free_words_slow(MetadataType mdtype) const { |
|
4788 assert(!_frozen, "sanity"); |
|
4789 if (mdtype == ClassType) { |
|
4790 return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0; |
|
4791 } else { |
|
4792 return vsm()->sum_free_in_chunks_in_use(); |
|
4793 } |
|
4794 } |
|
4795 |
|
4796 // Space capacity in the Metaspace. It includes |
|
4797 // space in the list of chunks from which allocations |
|
4798 // have been made. Don't include space in the global freelist and |
|
4799 // in the space available in the dictionary which |
|
4800 // is already counted in some chunk. |
|
4801 size_t Metaspace::capacity_words_slow(MetadataType mdtype) const { |
|
4802 if (mdtype == ClassType) { |
|
4803 return using_class_space() ? class_vsm()->sum_capacity_in_chunks_in_use() : 0; |
|
4804 } else { |
|
4805 return vsm()->sum_capacity_in_chunks_in_use(); |
|
4806 } |
|
4807 } |
|
4808 |
|
4809 size_t Metaspace::used_bytes_slow(MetadataType mdtype) const { |
|
4810 return used_words_slow(mdtype) * BytesPerWord; |
|
4811 } |
|
4812 |
|
4813 size_t Metaspace::capacity_bytes_slow(MetadataType mdtype) const { |
|
4814 return capacity_words_slow(mdtype) * BytesPerWord; |
|
4815 } |
|
4816 |
|
4817 size_t Metaspace::allocated_blocks_bytes() const { |
|
4818 return vsm()->allocated_blocks_bytes() + |
|
4819 (using_class_space() ? class_vsm()->allocated_blocks_bytes() : 0); |
|
4820 } |
|
4821 |
|
4822 size_t Metaspace::allocated_chunks_bytes() const { |
|
4823 return vsm()->allocated_chunks_bytes() + |
|
4824 (using_class_space() ? class_vsm()->allocated_chunks_bytes() : 0); |
|
4825 } |
|
4826 |
|
4827 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) { |
|
4828 assert(!_frozen, "sanity"); |
|
4829 assert(!SafepointSynchronize::is_at_safepoint() |
|
4830 || Thread::current()->is_VM_thread(), "should be the VM thread"); |
|
4831 |
|
4832 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag); |
|
4833 |
|
4834 if (is_class && using_class_space()) { |
|
4835 class_vsm()->deallocate(ptr, word_size); |
|
4836 } else { |
|
4837 vsm()->deallocate(ptr, word_size); |
|
4838 } |
|
4839 } |
4685 } |
4840 |
4686 |
4841 MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, |
4687 MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, |
4842 MetaspaceObj::Type type, TRAPS) { |
4688 MetaspaceObj::Type type, TRAPS) { |
4843 assert(!_frozen, "sanity"); |
4689 assert(!_frozen, "sanity"); |
4961 if (using_class_space()) { |
4802 if (using_class_space()) { |
4962 purge(ClassType); |
4803 purge(ClassType); |
4963 } |
4804 } |
4964 } |
4805 } |
4965 |
4806 |
4966 void Metaspace::print_on(outputStream* out) const { |
4807 bool Metaspace::contains(const void* ptr) { |
|
4808 if (MetaspaceShared::is_in_shared_metaspace(ptr)) { |
|
4809 return true; |
|
4810 } |
|
4811 return contains_non_shared(ptr); |
|
4812 } |
|
4813 |
|
4814 bool Metaspace::contains_non_shared(const void* ptr) { |
|
4815 if (using_class_space() && get_space_list(ClassType)->contains(ptr)) { |
|
4816 return true; |
|
4817 } |
|
4818 |
|
4819 return get_space_list(NonClassType)->contains(ptr); |
|
4820 } |
|
4821 |
|
4822 // ClassLoaderMetaspace |
|
4823 |
|
4824 ClassLoaderMetaspace::ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType type) { |
|
4825 initialize(lock, type); |
|
4826 } |
|
4827 |
|
4828 ClassLoaderMetaspace::~ClassLoaderMetaspace() { |
|
4829 delete _vsm; |
|
4830 if (Metaspace::using_class_space()) { |
|
4831 delete _class_vsm; |
|
4832 } |
|
4833 } |
|
4834 void ClassLoaderMetaspace::initialize_first_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype) { |
|
4835 Metachunk* chunk = get_initialization_chunk(type, mdtype); |
|
4836 if (chunk != NULL) { |
|
4837 // Add to this manager's list of chunks in use and current_chunk(). |
|
4838 get_space_manager(mdtype)->add_chunk(chunk, true); |
|
4839 } |
|
4840 } |
|
4841 |
|
4842 Metachunk* ClassLoaderMetaspace::get_initialization_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype) { |
|
4843 size_t chunk_word_size = get_space_manager(mdtype)->get_initial_chunk_size(type); |
|
4844 |
|
4845 // Get a chunk from the chunk freelist |
|
4846 Metachunk* chunk = Metaspace::get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size); |
|
4847 |
|
4848 if (chunk == NULL) { |
|
4849 chunk = Metaspace::get_space_list(mdtype)->get_new_chunk(chunk_word_size, |
|
4850 get_space_manager(mdtype)->medium_chunk_bunch()); |
|
4851 } |
|
4852 |
|
4853 return chunk; |
|
4854 } |
|
4855 |
|
4856 void ClassLoaderMetaspace::initialize(Mutex* lock, Metaspace::MetaspaceType type) { |
|
4857 Metaspace::verify_global_initialization(); |
|
4858 |
|
4859 // Allocate SpaceManager for metadata objects. |
|
4860 _vsm = new SpaceManager(Metaspace::NonClassType, type, lock); |
|
4861 |
|
4862 if (Metaspace::using_class_space()) { |
|
4863 // Allocate SpaceManager for classes. |
|
4864 _class_vsm = new SpaceManager(Metaspace::ClassType, type, lock); |
|
4865 } |
|
4866 |
|
4867 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); |
|
4868 |
|
4869 // Allocate chunk for metadata objects |
|
4870 initialize_first_chunk(type, Metaspace::NonClassType); |
|
4871 |
|
4872 // Allocate chunk for class metadata objects |
|
4873 if (Metaspace::using_class_space()) { |
|
4874 initialize_first_chunk(type, Metaspace::ClassType); |
|
4875 } |
|
4876 } |
|
4877 |
|
4878 MetaWord* ClassLoaderMetaspace::allocate(size_t word_size, Metaspace::MetadataType mdtype) { |
|
4879 Metaspace::assert_not_frozen(); |
|
4880 // Don't use class_vsm() unless UseCompressedClassPointers is true. |
|
4881 if (Metaspace::is_class_space_allocation(mdtype)) { |
|
4882 return class_vsm()->allocate(word_size); |
|
4883 } else { |
|
4884 return vsm()->allocate(word_size); |
|
4885 } |
|
4886 } |
|
4887 |
|
4888 MetaWord* ClassLoaderMetaspace::expand_and_allocate(size_t word_size, Metaspace::MetadataType mdtype) { |
|
4889 Metaspace::assert_not_frozen(); |
|
4890 size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord); |
|
4891 assert(delta_bytes > 0, "Must be"); |
|
4892 |
|
4893 size_t before = 0; |
|
4894 size_t after = 0; |
|
4895 MetaWord* res; |
|
4896 bool incremented; |
|
4897 |
|
4898 // Each thread increments the HWM at most once. Even if the thread fails to increment |
|
4899 // the HWM, an allocation is still attempted. This is because another thread must then |
|
4900 // have incremented the HWM and therefore the allocation might still succeed. |
|
4901 do { |
|
4902 incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before); |
|
4903 res = allocate(word_size, mdtype); |
|
4904 } while (!incremented && res == NULL); |
|
4905 |
|
4906 if (incremented) { |
|
4907 Metaspace::tracer()->report_gc_threshold(before, after, |
|
4908 MetaspaceGCThresholdUpdater::ExpandAndAllocate); |
|
4909 log_trace(gc, metaspace)("Increase capacity to GC from " SIZE_FORMAT " to " SIZE_FORMAT, before, after); |
|
4910 } |
|
4911 |
|
4912 return res; |
|
4913 } |
|
4914 |
|
4915 size_t ClassLoaderMetaspace::used_words_slow(Metaspace::MetadataType mdtype) const { |
|
4916 if (mdtype == Metaspace::ClassType) { |
|
4917 return Metaspace::using_class_space() ? class_vsm()->sum_used_in_chunks_in_use() : 0; |
|
4918 } else { |
|
4919 return vsm()->sum_used_in_chunks_in_use(); // includes overhead! |
|
4920 } |
|
4921 } |
|
4922 |
|
4923 size_t ClassLoaderMetaspace::free_words_slow(Metaspace::MetadataType mdtype) const { |
|
4924 Metaspace::assert_not_frozen(); |
|
4925 if (mdtype == Metaspace::ClassType) { |
|
4926 return Metaspace::using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0; |
|
4927 } else { |
|
4928 return vsm()->sum_free_in_chunks_in_use(); |
|
4929 } |
|
4930 } |
|
4931 |
|
4932 // Space capacity in the Metaspace. It includes |
|
4933 // space in the list of chunks from which allocations |
|
4934 // have been made. Don't include space in the global freelist and |
|
4935 // in the space available in the dictionary which |
|
4936 // is already counted in some chunk. |
|
4937 size_t ClassLoaderMetaspace::capacity_words_slow(Metaspace::MetadataType mdtype) const { |
|
4938 if (mdtype == Metaspace::ClassType) { |
|
4939 return Metaspace::using_class_space() ? class_vsm()->sum_capacity_in_chunks_in_use() : 0; |
|
4940 } else { |
|
4941 return vsm()->sum_capacity_in_chunks_in_use(); |
|
4942 } |
|
4943 } |
|
4944 |
|
4945 size_t ClassLoaderMetaspace::used_bytes_slow(Metaspace::MetadataType mdtype) const { |
|
4946 return used_words_slow(mdtype) * BytesPerWord; |
|
4947 } |
|
4948 |
|
4949 size_t ClassLoaderMetaspace::capacity_bytes_slow(Metaspace::MetadataType mdtype) const { |
|
4950 return capacity_words_slow(mdtype) * BytesPerWord; |
|
4951 } |
|
4952 |
|
4953 size_t ClassLoaderMetaspace::allocated_blocks_bytes() const { |
|
4954 return vsm()->allocated_blocks_bytes() + |
|
4955 (Metaspace::using_class_space() ? class_vsm()->allocated_blocks_bytes() : 0); |
|
4956 } |
|
4957 |
|
4958 size_t ClassLoaderMetaspace::allocated_chunks_bytes() const { |
|
4959 return vsm()->allocated_chunks_bytes() + |
|
4960 (Metaspace::using_class_space() ? class_vsm()->allocated_chunks_bytes() : 0); |
|
4961 } |
|
4962 |
|
4963 void ClassLoaderMetaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) { |
|
4964 Metaspace::assert_not_frozen(); |
|
4965 assert(!SafepointSynchronize::is_at_safepoint() |
|
4966 || Thread::current()->is_VM_thread(), "should be the VM thread"); |
|
4967 |
|
4968 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag); |
|
4969 |
|
4970 if (is_class && Metaspace::using_class_space()) { |
|
4971 class_vsm()->deallocate(ptr, word_size); |
|
4972 } else { |
|
4973 vsm()->deallocate(ptr, word_size); |
|
4974 } |
|
4975 } |
|
4976 |
|
4977 size_t ClassLoaderMetaspace::class_chunk_size(size_t word_size) { |
|
4978 assert(Metaspace::using_class_space(), "Has to use class space"); |
|
4979 return class_vsm()->calc_chunk_size(word_size); |
|
4980 } |
|
4981 |
|
4982 void ClassLoaderMetaspace::print_on(outputStream* out) const { |
4967 // Print both class virtual space counts and metaspace. |
4983 // Print both class virtual space counts and metaspace. |
4968 if (Verbose) { |
4984 if (Verbose) { |
4969 vsm()->print_on(out); |
4985 vsm()->print_on(out); |
4970 if (using_class_space()) { |
4986 if (Metaspace::using_class_space()) { |
4971 class_vsm()->print_on(out); |
4987 class_vsm()->print_on(out); |
4972 } |
4988 } |
4973 } |
4989 } |
4974 } |
4990 } |
4975 |
4991 |
4976 bool Metaspace::contains(const void* ptr) { |
4992 void ClassLoaderMetaspace::verify() { |
4977 if (MetaspaceShared::is_in_shared_metaspace(ptr)) { |
|
4978 return true; |
|
4979 } |
|
4980 return contains_non_shared(ptr); |
|
4981 } |
|
4982 |
|
4983 bool Metaspace::contains_non_shared(const void* ptr) { |
|
4984 if (using_class_space() && get_space_list(ClassType)->contains(ptr)) { |
|
4985 return true; |
|
4986 } |
|
4987 |
|
4988 return get_space_list(NonClassType)->contains(ptr); |
|
4989 } |
|
4990 |
|
4991 void Metaspace::verify() { |
|
4992 vsm()->verify(); |
4993 vsm()->verify(); |
4993 if (using_class_space()) { |
4994 if (Metaspace::using_class_space()) { |
4994 class_vsm()->verify(); |
4995 class_vsm()->verify(); |
4995 } |
4996 } |
4996 } |
4997 } |
4997 |
4998 |
4998 void Metaspace::dump(outputStream* const out) const { |
4999 void ClassLoaderMetaspace::dump(outputStream* const out) const { |
4999 out->print_cr("\nVirtual space manager: " INTPTR_FORMAT, p2i(vsm())); |
5000 out->print_cr("\nVirtual space manager: " INTPTR_FORMAT, p2i(vsm())); |
5000 vsm()->dump(out); |
5001 vsm()->dump(out); |
5001 if (using_class_space()) { |
5002 if (Metaspace::using_class_space()) { |
5002 out->print_cr("\nClass space manager: " INTPTR_FORMAT, p2i(class_vsm())); |
5003 out->print_cr("\nClass space manager: " INTPTR_FORMAT, p2i(class_vsm())); |
5003 class_vsm()->dump(out); |
5004 class_vsm()->dump(out); |
5004 } |
5005 } |
5005 } |
5006 } |
|
5007 |
|
5008 |
5006 |
5009 |
5007 #ifdef ASSERT |
5010 #ifdef ASSERT |
5008 static void do_verify_chunk(Metachunk* chunk) { |
5011 static void do_verify_chunk(Metachunk* chunk) { |
5009 guarantee(chunk != NULL, "Sanity"); |
5012 guarantee(chunk != NULL, "Sanity"); |
5010 // Verify chunk itself; then verify that it is consistent with the |
5013 // Verify chunk itself; then verify that it is consistent with the |