Tue, 11 May 2010 14:35:43 -0700
6931180: Migration to recent versions of MS Platform SDK
6951582: Build problems on win64
Summary: Changes to enable building JDK7 with Microsoft Visual Studio 2010
Reviewed-by: ohair, art, ccheung, dcubed
duke@435 | 1 | /* |
xdono@772 | 2 | * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
duke@435 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@435 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
duke@435 | 21 | * have any questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
duke@435 | 25 | // All heaps contains a "permanent generation," containing permanent |
duke@435 | 26 | // (reflective) objects. This is like a regular generation in some ways, |
duke@435 | 27 | // but unlike one in others, and so is split apart. |
duke@435 | 28 | |
duke@435 | 29 | class PermanentGenerationSpec; |
duke@435 | 30 | |
duke@435 | 31 | // This is the "generation" view of a CompactingPermGen. |
ysr@1486 | 32 | // NOTE: the shared spaces used for CDS are here handled in |
ysr@1486 | 33 | // a somewhat awkward and potentially buggy fashion, see CR 6801625. |
ysr@1486 | 34 | // This infelicity should be fixed, see CR 6897789. |
duke@435 | 35 | class CompactingPermGenGen: public OneContigSpaceCardGeneration { |
duke@435 | 36 | friend class VMStructs; |
duke@435 | 37 | // Abstractly, this is a subtype that gets access to protected fields. |
duke@435 | 38 | friend class CompactingPermGen; |
duke@435 | 39 | |
duke@435 | 40 | private: |
duke@435 | 41 | // Shared spaces |
duke@435 | 42 | PermanentGenerationSpec* _spec; |
duke@435 | 43 | size_t _shared_space_size; |
duke@435 | 44 | VirtualSpace _ro_vs; |
duke@435 | 45 | VirtualSpace _rw_vs; |
duke@435 | 46 | VirtualSpace _md_vs; |
duke@435 | 47 | VirtualSpace _mc_vs; |
duke@435 | 48 | BlockOffsetSharedArray* _ro_bts; |
duke@435 | 49 | BlockOffsetSharedArray* _rw_bts; |
duke@435 | 50 | OffsetTableContigSpace* _ro_space; |
duke@435 | 51 | OffsetTableContigSpace* _rw_space; |
duke@435 | 52 | |
ysr@1486 | 53 | // With shared spaces there is a dichotomy in the use of the |
duke@435 | 54 | // _virtual_space of the generation. There is a portion of the |
duke@435 | 55 | // _virtual_space that is used for the unshared part of the |
duke@435 | 56 | // permanent generation and a portion that is reserved for the shared part. |
duke@435 | 57 | // The _reserved field in the generation represents both the |
duke@435 | 58 | // unshared and shared parts of the generation. The _reserved |
duke@435 | 59 | // variable is initialized for only the unshared part but is |
duke@435 | 60 | // later extended to include the shared part during initialization |
duke@435 | 61 | // if shared spaces are being used. |
duke@435 | 62 | // The reserved size for the _virtual_space for CompactingPermGenGen |
duke@435 | 63 | // is the size of the space for the permanent generation including the |
duke@435 | 64 | // the shared spaces. This can be seen by the use of MaxPermSize |
duke@435 | 65 | // in the allocation of PermanentGenerationSpec. The space for the |
duke@435 | 66 | // shared spaces is committed separately (???). |
duke@435 | 67 | // In general at initialization only a part of the |
duke@435 | 68 | // space for the unshared part of the permanent generation is |
duke@435 | 69 | // committed and more is committed as the permanent generation is |
duke@435 | 70 | // grown. In growing the permanent generation the capacity() and |
duke@435 | 71 | // max_capacity() of the generation are used. For the permanent |
duke@435 | 72 | // generation (implemented with a CompactingPermGenGen) the capacity() |
duke@435 | 73 | // is taken from the capacity of the space (_the_space variable used for the |
duke@435 | 74 | // unshared part of the generation) and the max_capacity() is based |
duke@435 | 75 | // on the size of the _reserved variable (which includes the size of the |
duke@435 | 76 | // shared spaces) minus the size of the shared spaces. |
duke@435 | 77 | |
duke@435 | 78 | // These values are redundant, but are called out separately to avoid |
duke@435 | 79 | // going through heap/space/gen pointers for performance. |
duke@435 | 80 | static HeapWord* unshared_bottom; |
duke@435 | 81 | static HeapWord* unshared_end; |
duke@435 | 82 | static HeapWord* shared_bottom; |
duke@435 | 83 | static HeapWord* readonly_bottom; |
duke@435 | 84 | static HeapWord* readonly_end; |
duke@435 | 85 | static HeapWord* readwrite_bottom; |
duke@435 | 86 | static HeapWord* readwrite_end; |
duke@435 | 87 | static HeapWord* miscdata_bottom; |
duke@435 | 88 | static HeapWord* miscdata_end; |
duke@435 | 89 | static HeapWord* misccode_bottom; |
duke@435 | 90 | static HeapWord* misccode_end; |
duke@435 | 91 | static HeapWord* shared_end; |
duke@435 | 92 | |
duke@435 | 93 | // List of klassOops whose vtbl entries are used to patch others. |
duke@435 | 94 | static void** _vtbl_list; |
duke@435 | 95 | |
duke@435 | 96 | // Performance Counters |
duke@435 | 97 | GenerationCounters* _gen_counters; |
duke@435 | 98 | CSpaceCounters* _space_counters; |
duke@435 | 99 | |
duke@435 | 100 | void initialize_performance_counters(); |
duke@435 | 101 | |
duke@435 | 102 | public: |
duke@435 | 103 | |
duke@435 | 104 | enum { |
duke@435 | 105 | vtbl_list_size = 16, // number of entries in the shared space vtable list. |
acorn@843 | 106 | num_virtuals = 200 // number of virtual methods in Klass (or |
duke@435 | 107 | // subclass) objects, or greater. |
duke@435 | 108 | }; |
duke@435 | 109 | |
duke@435 | 110 | enum { |
duke@435 | 111 | ro = 0, // read-only shared space in the heap |
duke@435 | 112 | rw = 1, // read-write shared space in the heap |
duke@435 | 113 | md = 2, // miscellaneous data for initializing tables, etc. |
duke@435 | 114 | mc = 3, // miscellaneous code - vtable replacement. |
duke@435 | 115 | n_regions = 4 |
duke@435 | 116 | }; |
duke@435 | 117 | |
duke@435 | 118 | CompactingPermGenGen(ReservedSpace rs, ReservedSpace shared_rs, |
duke@435 | 119 | size_t initial_byte_size, int level, GenRemSet* remset, |
duke@435 | 120 | ContiguousSpace* space, |
duke@435 | 121 | PermanentGenerationSpec* perm_spec); |
duke@435 | 122 | |
duke@435 | 123 | const char* name() const { |
duke@435 | 124 | return "compacting perm gen"; |
duke@435 | 125 | } |
duke@435 | 126 | |
duke@435 | 127 | const char* short_name() const { |
duke@435 | 128 | return "Perm"; |
duke@435 | 129 | } |
duke@435 | 130 | |
duke@435 | 131 | // Return the maximum capacity for the object space. This |
duke@435 | 132 | // explicitly does not include the shared spaces. |
duke@435 | 133 | size_t max_capacity() const; |
duke@435 | 134 | |
duke@435 | 135 | void update_counters(); |
duke@435 | 136 | |
duke@435 | 137 | void compute_new_size() { |
duke@435 | 138 | assert(false, "Should not call this -- handled at PermGen level."); |
duke@435 | 139 | } |
duke@435 | 140 | |
duke@435 | 141 | bool must_be_youngest() const { return false; } |
duke@435 | 142 | bool must_be_oldest() const { return false; } |
duke@435 | 143 | |
duke@435 | 144 | OffsetTableContigSpace* ro_space() const { return _ro_space; } |
duke@435 | 145 | OffsetTableContigSpace* rw_space() const { return _rw_space; } |
duke@435 | 146 | VirtualSpace* md_space() { return &_md_vs; } |
duke@435 | 147 | VirtualSpace* mc_space() { return &_mc_vs; } |
duke@435 | 148 | ContiguousSpace* unshared_space() const { return _the_space; } |
duke@435 | 149 | |
duke@435 | 150 | static bool inline is_shared(const oopDesc* p) { |
duke@435 | 151 | return (HeapWord*)p >= shared_bottom && (HeapWord*)p < shared_end; |
duke@435 | 152 | } |
duke@435 | 153 | // RedefineClasses note: this tester is used to check residence of |
duke@435 | 154 | // the specified oop in the shared readonly space and not whether |
duke@435 | 155 | // the oop is readonly. |
duke@435 | 156 | static bool inline is_shared_readonly(const oopDesc* p) { |
duke@435 | 157 | return (HeapWord*)p >= readonly_bottom && (HeapWord*)p < readonly_end; |
duke@435 | 158 | } |
duke@435 | 159 | // RedefineClasses note: this tester is used to check residence of |
duke@435 | 160 | // the specified oop in the shared readwrite space and not whether |
duke@435 | 161 | // the oop is readwrite. |
duke@435 | 162 | static bool inline is_shared_readwrite(const oopDesc* p) { |
duke@435 | 163 | return (HeapWord*)p >= readwrite_bottom && (HeapWord*)p < readwrite_end; |
duke@435 | 164 | } |
duke@435 | 165 | |
duke@435 | 166 | bool is_in_unshared(const void* p) const { |
duke@435 | 167 | return OneContigSpaceCardGeneration::is_in(p); |
duke@435 | 168 | } |
duke@435 | 169 | |
duke@435 | 170 | bool is_in_shared(const void* p) const { |
duke@435 | 171 | return p >= shared_bottom && p < shared_end; |
duke@435 | 172 | } |
duke@435 | 173 | |
duke@435 | 174 | inline bool is_in(const void* p) const { |
duke@435 | 175 | return is_in_unshared(p) || is_in_shared(p); |
duke@435 | 176 | } |
duke@435 | 177 | |
duke@435 | 178 | inline PermanentGenerationSpec* spec() const { return _spec; } |
duke@435 | 179 | inline void set_spec(PermanentGenerationSpec* spec) { _spec = spec; } |
duke@435 | 180 | |
duke@435 | 181 | void pre_adjust_pointers(); |
duke@435 | 182 | void adjust_pointers(); |
duke@435 | 183 | void space_iterate(SpaceClosure* blk, bool usedOnly = false); |
duke@435 | 184 | void print_on(outputStream* st) const; |
duke@435 | 185 | void younger_refs_iterate(OopsInGenClosure* blk); |
duke@435 | 186 | void compact(); |
duke@435 | 187 | void post_compact(); |
duke@435 | 188 | size_t contiguous_available() const; |
duke@435 | 189 | |
duke@435 | 190 | void clear_remembered_set(); |
duke@435 | 191 | void invalidate_remembered_set(); |
duke@435 | 192 | |
duke@435 | 193 | inline bool block_is_obj(const HeapWord* addr) const { |
duke@435 | 194 | if (addr < the_space()->top()) return true; |
duke@435 | 195 | else if (addr < the_space()->end()) return false; |
duke@435 | 196 | else if (addr < ro_space()->top()) return true; |
duke@435 | 197 | else if (addr < ro_space()->end()) return false; |
duke@435 | 198 | else if (addr < rw_space()->top()) return true; |
duke@435 | 199 | else return false; |
duke@435 | 200 | } |
duke@435 | 201 | |
duke@435 | 202 | |
duke@435 | 203 | inline size_t block_size(const HeapWord* addr) const { |
duke@435 | 204 | if (addr < the_space()->top()) { |
duke@435 | 205 | return oop(addr)->size(); |
duke@435 | 206 | } |
duke@435 | 207 | else if (addr < the_space()->end()) { |
duke@435 | 208 | assert(addr == the_space()->top(), "non-block head arg to block_size"); |
duke@435 | 209 | return the_space()->end() - the_space()->top(); |
duke@435 | 210 | } |
duke@435 | 211 | |
duke@435 | 212 | else if (addr < ro_space()->top()) { |
duke@435 | 213 | return oop(addr)->size(); |
duke@435 | 214 | } |
duke@435 | 215 | else if (addr < ro_space()->end()) { |
duke@435 | 216 | assert(addr == ro_space()->top(), "non-block head arg to block_size"); |
duke@435 | 217 | return ro_space()->end() - ro_space()->top(); |
duke@435 | 218 | } |
duke@435 | 219 | |
duke@435 | 220 | else if (addr < rw_space()->top()) { |
duke@435 | 221 | return oop(addr)->size(); |
duke@435 | 222 | } |
duke@435 | 223 | else { |
duke@435 | 224 | assert(addr == rw_space()->top(), "non-block head arg to block_size"); |
duke@435 | 225 | return rw_space()->end() - rw_space()->top(); |
duke@435 | 226 | } |
duke@435 | 227 | } |
duke@435 | 228 | |
duke@435 | 229 | static void generate_vtable_methods(void** vtbl_list, |
duke@435 | 230 | void** vtable, |
duke@435 | 231 | char** md_top, char* md_end, |
duke@435 | 232 | char** mc_top, char* mc_end); |
duke@435 | 233 | |
duke@435 | 234 | void verify(bool allow_dirty); |
duke@435 | 235 | |
duke@435 | 236 | // Serialization |
duke@435 | 237 | static void initialize_oops() KERNEL_RETURN; |
duke@435 | 238 | static void serialize_oops(SerializeOopClosure* soc); |
duke@435 | 239 | void serialize_bts(SerializeOopClosure* soc); |
duke@435 | 240 | |
duke@435 | 241 | // Initiate dumping of shared file. |
duke@435 | 242 | static jint dump_shared(GrowableArray<oop>* class_promote_order, TRAPS); |
duke@435 | 243 | |
duke@435 | 244 | // JVM/TI RedefineClasses() support: |
duke@435 | 245 | // Remap the shared readonly space to shared readwrite, private if |
duke@435 | 246 | // sharing is enabled. Simply returns true if sharing is not enabled |
duke@435 | 247 | // or if the remapping has already been done by a prior call. |
duke@435 | 248 | static bool remap_shared_readonly_as_readwrite(); |
duke@435 | 249 | }; |