1 /*
   2  * Copyright (c) 2001, 2005, 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 
  25 # include "incls/_precompiled.incl"
  26 # include "incls/_generationSpec.cpp.incl"
  27 
  28 Generation* GenerationSpec::init(ReservedSpace rs, int level,
  29                                  GenRemSet* remset) {
  30   switch (name()) {
  31     case Generation::DefNew:
  32       return new DefNewGeneration(rs, init_size(), level);
  33 
  34     case Generation::MarkSweepCompact:
  35       return new TenuredGeneration(rs, init_size(), level, remset);
  36 
  37 #ifndef SERIALGC
  38     case Generation::ParNew:
  39       return new ParNewGeneration(rs, init_size(), level);
  40 
  41     case Generation::ASParNew:
  42       return new ASParNewGeneration(rs,
  43                                     init_size(),
  44                                     init_size() /* min size */,
  45                                     level);
  46 
  47     case Generation::ConcurrentMarkSweep: {
  48       assert(UseConcMarkSweepGC, "UseConcMarkSweepGC should be set");
  49       CardTableRS* ctrs = remset->as_CardTableRS();
  50       if (ctrs == NULL) {
  51         vm_exit_during_initialization("Rem set incompatibility.");
  52       }
  53       // Otherwise
  54       // The constructor creates the CMSCollector if needed,
  55       // else registers with an existing CMSCollector
  56 
  57       ConcurrentMarkSweepGeneration* g = NULL;
  58       g = new ConcurrentMarkSweepGeneration(rs,
  59                  init_size(), level, ctrs, UseCMSAdaptiveFreeLists,
  60                  (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice);
  61 
  62       g->initialize_performance_counters();
  63 
  64       return g;
  65     }
  66 
  67     case Generation::ASConcurrentMarkSweep: {
  68       assert(UseConcMarkSweepGC, "UseConcMarkSweepGC should be set");
  69       CardTableRS* ctrs = remset->as_CardTableRS();
  70       if (ctrs == NULL) {
  71         vm_exit_during_initialization("Rem set incompatibility.");
  72       }
  73       // Otherwise
  74       // The constructor creates the CMSCollector if needed,
  75       // else registers with an existing CMSCollector
  76 
  77       ASConcurrentMarkSweepGeneration* g = NULL;
  78       g = new ASConcurrentMarkSweepGeneration(rs,
  79                  init_size(), level, ctrs, UseCMSAdaptiveFreeLists,
  80                  (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice);
  81 
  82       g->initialize_performance_counters();
  83 
  84       return g;
  85     }
  86 #endif // SERIALGC
  87 
  88     default:
  89       guarantee(false, "unrecognized GenerationName");
  90       return NULL;
  91   }
  92 }
  93 
  94 
  95 PermanentGenerationSpec::PermanentGenerationSpec(PermGen::Name name,
  96                       size_t init_size, size_t max_size,
  97                       size_t read_only_size, size_t read_write_size,
  98                       size_t misc_data_size, size_t misc_code_size) {
  99   _name = name;
 100   _init_size = init_size;
 101 
 102   if (UseSharedSpaces || DumpSharedSpaces) {
 103     _enable_shared_spaces = true;
 104     if (UseSharedSpaces) {
 105       // Override shared space sizes from those in the file.
 106       FileMapInfo* mapinfo = FileMapInfo::current_info();
 107       _read_only_size = mapinfo->space_capacity(CompactingPermGenGen::ro);
 108       _read_write_size = mapinfo->space_capacity(CompactingPermGenGen::rw);
 109       _misc_data_size = mapinfo->space_capacity(CompactingPermGenGen::md);
 110       _misc_code_size = mapinfo->space_capacity(CompactingPermGenGen::mc);
 111     } else {
 112       _read_only_size = read_only_size;
 113       _read_write_size = read_write_size;
 114       _misc_data_size = misc_data_size;
 115       _misc_code_size = misc_code_size;
 116     }
 117   } else {
 118     _enable_shared_spaces = false;
 119     _read_only_size = 0;
 120     _read_write_size = 0;
 121     _misc_data_size = 0;
 122     _misc_code_size = 0;
 123   }
 124 
 125   _max_size = max_size;
 126 }
 127 
 128 
 129 PermGen* PermanentGenerationSpec::init(ReservedSpace rs,
 130                                        size_t init_size,
 131                                        GenRemSet *remset) {
 132 
 133   // Break the reserved spaces into pieces for the permanent space
 134   // and the shared spaces.
 135   ReservedSpace perm_rs = rs.first_part(_max_size, UseSharedSpaces,
 136                                         UseSharedSpaces);
 137   ReservedSpace shared_rs = rs.last_part(_max_size);
 138 
 139   if (enable_shared_spaces()) {
 140     if (!perm_rs.is_reserved() ||
 141         perm_rs.base() + perm_rs.size() != shared_rs.base()) {
 142       FileMapInfo* mapinfo = FileMapInfo::current_info();
 143       mapinfo->fail_continue("Sharing disabled - unable to "
 144                                  "reserve address space.");
 145       shared_rs.release();
 146       disable_sharing();
 147     }
 148   }
 149 
 150   switch (name()) {
 151     case PermGen::MarkSweepCompact:
 152       return new CompactingPermGen(perm_rs, shared_rs, init_size, remset, this);
 153 
 154 #ifndef SERIALGC
 155     case PermGen::MarkSweep:
 156       guarantee(false, "NYI");
 157       return NULL;
 158 
 159     case PermGen::ConcurrentMarkSweep: {
 160       assert(UseConcMarkSweepGC, "UseConcMarkSweepGC should be set");
 161       CardTableRS* ctrs = remset->as_CardTableRS();
 162       if (ctrs == NULL) {
 163         vm_exit_during_initialization("RemSet/generation incompatibility.");
 164       }
 165       // XXXPERM
 166       return new CMSPermGen(perm_rs, init_size, ctrs,
 167                    (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice);
 168     }
 169 #endif // SERIALGC
 170     default:
 171       guarantee(false, "unrecognized GenerationName");
 172       return NULL;
 173   }
 174 }
 175 
 176 
 177 // Alignment
 178 void PermanentGenerationSpec::align(size_t alignment) {
 179   _init_size       = align_size_up(_init_size,       alignment);
 180   _max_size        = align_size_up(_max_size,        alignment);
 181   _read_only_size  = align_size_up(_read_only_size,  alignment);
 182   _read_write_size = align_size_up(_read_write_size, alignment);
 183   _misc_data_size  = align_size_up(_misc_data_size,  alignment);
 184   _misc_code_size  = align_size_up(_misc_code_size,  alignment);
 185 
 186   assert(enable_shared_spaces() || (_read_only_size + _read_write_size == 0),
 187          "Shared space when disabled?");
 188 }