src/hotspot/share/gc/epsilon/epsilonCollectedHeap.cpp
branchepsilon-gc-branch
changeset 55939 c5c3e1a5c3f0
parent 55938 d7b4990d04d6
child 55974 06122633fead
equal deleted inserted replaced
55938:d7b4990d04d6 55939:c5c3e1a5c3f0
     1 /*
       
     2  * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
       
     3  *
       
     4  * This code is free software; you can redistribute it and/or modify it
       
     5  * under the terms of the GNU General Public License version 2 only, as
       
     6  * published by the Free Software Foundation.
       
     7  *
       
     8  * This code is distributed in the hope that it will be useful, but WITHOUT
       
     9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    11  * version 2 for more details (a copy is included in the LICENSE file that
       
    12  * accompanied this code).
       
    13  *
       
    14  * You should have received a copy of the GNU General Public License version
       
    15  * 2 along with this work; if not, write to the Free Software Foundation,
       
    16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    17  *
       
    18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    19  * or visit www.oracle.com if you need additional information or have any
       
    20  * questions.
       
    21  *
       
    22  */
       
    23 
       
    24 #include "precompiled.hpp"
       
    25 #include "oops/oop.hpp"
       
    26 #include "oops/oop.inline.hpp"
       
    27 #include "gc/epsilon/epsilonCollectedHeap.hpp"
       
    28 
       
    29 jint EpsilonCollectedHeap::initialize() {
       
    30   CollectedHeap::pre_initialize();
       
    31 
       
    32   size_t init_byte_size = _policy->initial_heap_byte_size();
       
    33   size_t max_byte_size = _policy->max_heap_byte_size();
       
    34   size_t align = _policy->heap_alignment();
       
    35 
       
    36   ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size,  align);
       
    37   _virtual_space.initialize(heap_rs, init_byte_size);
       
    38 
       
    39   MemRegion committed_region((HeapWord*)_virtual_space.low(), (HeapWord*)_virtual_space.high());
       
    40   MemRegion reserved_region((HeapWord*)_virtual_space.low_boundary(), (HeapWord*)_virtual_space.high_boundary());
       
    41 
       
    42   initialize_reserved_region(reserved_region.start(), reserved_region.end());
       
    43 
       
    44   _space = new ContiguousSpace();
       
    45   _space->initialize(committed_region, true, true);
       
    46 
       
    47   EpsilonBarrierSet* bs = new EpsilonBarrierSet();
       
    48   set_barrier_set(bs);
       
    49 
       
    50   _max_tlab_size = MIN2(CollectedHeap::max_tlab_size(), EpsilonMaxTLABSize / HeapWordSize);
       
    51 
       
    52   _monitoring_support = new EpsilonMonitoringSupport(this);
       
    53   _last_counter_update = 0;
       
    54 
       
    55   if (init_byte_size != max_byte_size) {
       
    56     log_info(gc)("Initialized with " SIZE_FORMAT "M heap, resizeable to up to " SIZE_FORMAT "M heap with " SIZE_FORMAT "M steps",
       
    57                  init_byte_size / M, max_byte_size / M, EpsilonMinHeapExpand / M);
       
    58   } else {
       
    59     log_info(gc)("Initialized with " SIZE_FORMAT "M non-resizeable heap", init_byte_size / M);
       
    60   }
       
    61   if (UseTLAB) {
       
    62     log_info(gc)("Using TLAB allocation; min: " SIZE_FORMAT "K, max: " SIZE_FORMAT "K",
       
    63                                 ThreadLocalAllocBuffer::min_size()*HeapWordSize / K,
       
    64                                 _max_tlab_size*HeapWordSize / K);
       
    65   } else {
       
    66     log_info(gc)("Not using TLAB allocation");
       
    67   }
       
    68 
       
    69   return JNI_OK;
       
    70 }
       
    71 
       
    72 size_t EpsilonCollectedHeap::unsafe_max_tlab_alloc(Thread *thr) const {
       
    73   // This is the only way we can control TLAB sizes without having safepoints.
       
    74   // Implement exponential expansion within [MinTLABSize; _max_tlab_size], based
       
    75   // on previously "used" TLAB size.
       
    76 
       
    77   size_t size = MIN2(_max_tlab_size * HeapWordSize, MAX2(MinTLABSize, thr->tlab().used() * HeapWordSize * 2));
       
    78 
       
    79   if (log_is_enabled(Trace, gc)) {
       
    80     ResourceMark rm;
       
    81     log_trace(gc)(
       
    82             "Selecting TLAB size for \"%s\" (Desired: " SIZE_FORMAT "K, Used: " SIZE_FORMAT "K) -> " SIZE_FORMAT "K",
       
    83             Thread::current()->name(),
       
    84             thr->tlab().desired_size() * HeapWordSize / K,
       
    85             thr->tlab().used() * HeapWordSize / K,
       
    86             size / K);
       
    87   }
       
    88 
       
    89   return size;
       
    90 }
       
    91 
       
    92 EpsilonCollectedHeap* EpsilonCollectedHeap::heap() {
       
    93   CollectedHeap* heap = Universe::heap();
       
    94   assert(heap != NULL, "Uninitialized access to EpsilonCollectedHeap::heap()");
       
    95   assert(heap->kind() == CollectedHeap::EpsilonCollectedHeap, "Not a EpsilonCollectedHeap");
       
    96   return (EpsilonCollectedHeap*)heap;
       
    97 }
       
    98 
       
    99 HeapWord* EpsilonCollectedHeap::allocate_work(size_t size) {
       
   100   HeapWord* res = _space->par_allocate(size);
       
   101 
       
   102   while (res == NULL) {
       
   103     // Allocation failed, attempt expansion, and retry:
       
   104     MutexLockerEx ml(Heap_lock);
       
   105     if (!_virtual_space.expand_by(MAX2(size, EpsilonMinHeapExpand))) {
       
   106       return NULL;
       
   107     }
       
   108     _space->set_end((HeapWord *) _virtual_space.high());
       
   109     res = _space->par_allocate(size);
       
   110   }
       
   111 
       
   112   size_t used = _space->used();
       
   113   if (used - _last_counter_update >= 1024 * 1024) {
       
   114     _last_counter_update = used;
       
   115     _monitoring_support->update_counters();
       
   116   }
       
   117   return res;
       
   118 }
       
   119 
       
   120 HeapWord* EpsilonCollectedHeap::allocate_new_tlab(size_t size) {
       
   121   return allocate_work(size);
       
   122 }
       
   123 
       
   124 HeapWord* EpsilonCollectedHeap::mem_allocate(size_t size, bool *gc_overhead_limit_was_exceeded) {
       
   125   *gc_overhead_limit_was_exceeded = false;
       
   126   return allocate_work(size);
       
   127 }
       
   128 
       
   129 void EpsilonCollectedHeap::collect(GCCause::Cause cause) {
       
   130   log_info(gc)("GC was triggered with cause \"%s\". Ignoring.", GCCause::to_string(cause));
       
   131   _monitoring_support->update_counters();
       
   132 }
       
   133 
       
   134 void EpsilonCollectedHeap::do_full_collection(bool clear_all_soft_refs) {
       
   135   log_info(gc)("Full GC was triggered with cause \"%s\". Ignoring.", GCCause::to_string(gc_cause()));
       
   136   _monitoring_support->update_counters();
       
   137 }
       
   138 
       
   139 void EpsilonCollectedHeap::safe_object_iterate(ObjectClosure *cl) {
       
   140   _space->safe_object_iterate(cl);
       
   141 }
       
   142 
       
   143 void EpsilonCollectedHeap::print_on(outputStream *st) const {
       
   144   st->print_cr("Epsilon Heap");
       
   145 
       
   146   // Cast away constness:
       
   147   ((VirtualSpace)_virtual_space).print_on(st);
       
   148 
       
   149   st->print_cr("Allocation space:");
       
   150   _space->print_on(st);
       
   151 }
       
   152 
       
   153 void EpsilonCollectedHeap::print_tracing_info() const {
       
   154   Log(gc) log;
       
   155   size_t allocated_kb = used() / K;
       
   156   log.info("Total allocated: " SIZE_FORMAT " KB",
       
   157            allocated_kb);
       
   158   log.info("Average allocation rate: " SIZE_FORMAT " KB/sec",
       
   159            allocated_kb * NANOSECS_PER_SEC / os::elapsed_counter());
       
   160 }