src/hotspot/share/memory/metaspace/classLoaderMetaspace.cpp
branchstuefe-improved-metaspace
changeset 57464 32e61f51ee09
equal deleted inserted replaced
55634:0f1e29c77e50 57464:32e61f51ee09
       
     1 /*
       
     2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 #include "precompiled.hpp"
       
    25 
       
    26 #include "logging/log.hpp"
       
    27 #include "memory/metaspace.hpp"
       
    28 #include "memory/metaspace/chunkAllocSequence.hpp"
       
    29 #include "memory/metaspace/classLoaderMetaspace.hpp"
       
    30 #include "memory/metaspace/metaspaceCommon.hpp"
       
    31 #include "runtime/atomic.hpp"
       
    32 #include "utilities/debug.hpp"
       
    33 
       
    34 namespace metaspace {
       
    35 
       
    36 ClassLoaderMetaspace::ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType space_type)
       
    37   : _lock(lock)
       
    38   , _space_type(space_type)
       
    39   , _non_class_space_manager(NULL)
       
    40   , _class_space_manager(NULL)
       
    41 {
       
    42   DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_metaspace_births));
       
    43 
       
    44   // Initialize non-class spacemanager
       
    45   _non_class_space_manager = new SpaceManager(
       
    46       Metaspace::chunk_manager_metadata(),
       
    47       ChunkAllocSequence::alloc_sequence_by_space_type(space_type, false),
       
    48       lock);
       
    49 
       
    50   // If needed, initialize class spacemanager
       
    51   if (Metaspace::using_class_space()) {
       
    52     _class_space_manager = new SpaceManager(
       
    53         Metaspace::chunk_manager_class(),
       
    54         ChunkAllocSequence::alloc_sequence_by_space_type(space_type, true),
       
    55         lock);
       
    56   }
       
    57 
       
    58 }
       
    59 
       
    60 ClassLoaderMetaspace::~ClassLoaderMetaspace() {
       
    61   Metaspace::assert_not_frozen();
       
    62   DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_metaspace_deaths));
       
    63   delete _non_class_space_manager;
       
    64   delete _class_space_manager;
       
    65 }
       
    66 
       
    67 // Allocate word_size words from Metaspace.
       
    68 MetaWord* ClassLoaderMetaspace::allocate(size_t word_size, bool is_class) {
       
    69   Metaspace::assert_not_frozen();
       
    70   DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_allocs));
       
    71   if (is_class && Metaspace::using_class_space()) {
       
    72     return class_space_manager()->allocate(word_size);
       
    73   } else {
       
    74     return non_class_space_manager()->allocate(word_size);
       
    75   }
       
    76 }
       
    77 
       
    78 // Attempt to expand the GC threshold to be good for at least another word_size words
       
    79 // and allocate. Returns NULL if failure. Used during Metaspace GC.
       
    80 MetaWord* ClassLoaderMetaspace::expand_GC_threshold_and_allocate(size_t word_size, bool is_class) {
       
    81   Metaspace::assert_not_frozen();
       
    82   size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord);
       
    83   assert(delta_bytes > 0, "Must be");
       
    84 
       
    85   size_t before = 0;
       
    86   size_t after = 0;
       
    87   bool can_retry = true;
       
    88   MetaWord* res;
       
    89   bool incremented;
       
    90 
       
    91   // Each thread increments the HWM at most once. Even if the thread fails to increment
       
    92   // the HWM, an allocation is still attempted. This is because another thread must then
       
    93   // have incremented the HWM and therefore the allocation might still succeed.
       
    94   do {
       
    95     incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before, &can_retry);
       
    96     res = allocate(word_size, is_class);
       
    97   } while (!incremented && res == NULL && can_retry);
       
    98 
       
    99   if (incremented) {
       
   100     Metaspace::tracer()->report_gc_threshold(before, after,
       
   101                                   MetaspaceGCThresholdUpdater::ExpandAndAllocate);
       
   102     log_trace(gc, metaspace)("Increase capacity to GC from " SIZE_FORMAT " to " SIZE_FORMAT, before, after);
       
   103   }
       
   104 
       
   105   return res;
       
   106 }
       
   107 
       
   108 // Prematurely returns a metaspace allocation to the _block_freelists
       
   109 // because it is not needed anymore.
       
   110 void ClassLoaderMetaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
       
   111 
       
   112   Metaspace::assert_not_frozen();
       
   113   DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_external_deallocs));
       
   114 
       
   115   if (is_class && Metaspace::using_class_space()) {
       
   116     class_space_manager()->deallocate(ptr, word_size);
       
   117   } else {
       
   118     non_class_space_manager()->deallocate(ptr, word_size);
       
   119   }
       
   120 
       
   121 }
       
   122 
       
   123 
       
   124 
       
   125 
       
   126 
       
   127 
       
   128