0N/A/*
4170N/A * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#ifndef SHARE_VM_MEMORY_COMPACTINGPERMGENGEN_HPP
1879N/A#define SHARE_VM_MEMORY_COMPACTINGPERMGENGEN_HPP
1879N/A
1879N/A#include "gc_implementation/shared/generationCounters.hpp"
1879N/A#include "memory/space.hpp"
1879N/A
0N/A// All heaps contains a "permanent generation," containing permanent
0N/A// (reflective) objects. This is like a regular generation in some ways,
0N/A// but unlike one in others, and so is split apart.
0N/A
0N/Aclass PermanentGenerationSpec;
0N/A
0N/A// This is the "generation" view of a CompactingPermGen.
1051N/A// NOTE: the shared spaces used for CDS are here handled in
1051N/A// a somewhat awkward and potentially buggy fashion, see CR 6801625.
1051N/A// This infelicity should be fixed, see CR 6897789.
0N/Aclass CompactingPermGenGen: public OneContigSpaceCardGeneration {
0N/A friend class VMStructs;
0N/A // Abstractly, this is a subtype that gets access to protected fields.
0N/A friend class CompactingPermGen;
0N/A
0N/Aprivate:
0N/A // Shared spaces
0N/A PermanentGenerationSpec* _spec;
0N/A size_t _shared_space_size;
0N/A VirtualSpace _ro_vs;
0N/A VirtualSpace _rw_vs;
0N/A VirtualSpace _md_vs;
0N/A VirtualSpace _mc_vs;
0N/A BlockOffsetSharedArray* _ro_bts;
0N/A BlockOffsetSharedArray* _rw_bts;
0N/A OffsetTableContigSpace* _ro_space;
0N/A OffsetTableContigSpace* _rw_space;
0N/A
1051N/A // With shared spaces there is a dichotomy in the use of the
0N/A // _virtual_space of the generation. There is a portion of the
0N/A // _virtual_space that is used for the unshared part of the
0N/A // permanent generation and a portion that is reserved for the shared part.
0N/A // The _reserved field in the generation represents both the
0N/A // unshared and shared parts of the generation. The _reserved
0N/A // variable is initialized for only the unshared part but is
0N/A // later extended to include the shared part during initialization
0N/A // if shared spaces are being used.
0N/A // The reserved size for the _virtual_space for CompactingPermGenGen
0N/A // is the size of the space for the permanent generation including the
0N/A // the shared spaces. This can be seen by the use of MaxPermSize
0N/A // in the allocation of PermanentGenerationSpec. The space for the
0N/A // shared spaces is committed separately (???).
0N/A // In general at initialization only a part of the
0N/A // space for the unshared part of the permanent generation is
0N/A // committed and more is committed as the permanent generation is
0N/A // grown. In growing the permanent generation the capacity() and
0N/A // max_capacity() of the generation are used. For the permanent
0N/A // generation (implemented with a CompactingPermGenGen) the capacity()
0N/A // is taken from the capacity of the space (_the_space variable used for the
0N/A // unshared part of the generation) and the max_capacity() is based
0N/A // on the size of the _reserved variable (which includes the size of the
0N/A // shared spaces) minus the size of the shared spaces.
0N/A
0N/A // These values are redundant, but are called out separately to avoid
0N/A // going through heap/space/gen pointers for performance.
0N/A static HeapWord* unshared_bottom;
0N/A static HeapWord* unshared_end;
0N/A static HeapWord* shared_bottom;
0N/A static HeapWord* readonly_bottom;
0N/A static HeapWord* readonly_end;
0N/A static HeapWord* readwrite_bottom;
0N/A static HeapWord* readwrite_end;
0N/A static HeapWord* miscdata_bottom;
0N/A static HeapWord* miscdata_end;
0N/A static HeapWord* misccode_bottom;
0N/A static HeapWord* misccode_end;
0N/A static HeapWord* shared_end;
0N/A
0N/A // Performance Counters
0N/A GenerationCounters* _gen_counters;
0N/A CSpaceCounters* _space_counters;
0N/A
0N/A void initialize_performance_counters();
0N/A
0N/Apublic:
0N/A
0N/A enum {
2223N/A vtbl_list_size = 17, // number of entries in the shared space vtable list.
408N/A num_virtuals = 200 // number of virtual methods in Klass (or
0N/A // subclass) objects, or greater.
0N/A };
0N/A
0N/A enum {
0N/A ro = 0, // read-only shared space in the heap
0N/A rw = 1, // read-write shared space in the heap
0N/A md = 2, // miscellaneous data for initializing tables, etc.
0N/A mc = 3, // miscellaneous code - vtable replacement.
0N/A n_regions = 4
0N/A };
0N/A
0N/A CompactingPermGenGen(ReservedSpace rs, ReservedSpace shared_rs,
0N/A size_t initial_byte_size, int level, GenRemSet* remset,
0N/A ContiguousSpace* space,
0N/A PermanentGenerationSpec* perm_spec);
0N/A
0N/A const char* name() const {
0N/A return "compacting perm gen";
0N/A }
0N/A
0N/A const char* short_name() const {
0N/A return "Perm";
0N/A }
0N/A
0N/A // Return the maximum capacity for the object space. This
0N/A // explicitly does not include the shared spaces.
0N/A size_t max_capacity() const;
0N/A
0N/A void update_counters();
0N/A
0N/A void compute_new_size() {
0N/A assert(false, "Should not call this -- handled at PermGen level.");
0N/A }
0N/A
0N/A bool must_be_youngest() const { return false; }
0N/A bool must_be_oldest() const { return false; }
0N/A
0N/A OffsetTableContigSpace* ro_space() const { return _ro_space; }
0N/A OffsetTableContigSpace* rw_space() const { return _rw_space; }
0N/A VirtualSpace* md_space() { return &_md_vs; }
0N/A VirtualSpace* mc_space() { return &_mc_vs; }
0N/A ContiguousSpace* unshared_space() const { return _the_space; }
0N/A
2062N/A static bool inline is_shared(const void* p) {
2062N/A return p >= shared_bottom && p < shared_end;
0N/A }
0N/A // RedefineClasses note: this tester is used to check residence of
0N/A // the specified oop in the shared readonly space and not whether
0N/A // the oop is readonly.
2062N/A static bool inline is_shared_readonly(const void* p) {
2062N/A return p >= readonly_bottom && p < readonly_end;
0N/A }
0N/A // RedefineClasses note: this tester is used to check residence of
0N/A // the specified oop in the shared readwrite space and not whether
0N/A // the oop is readwrite.
2062N/A static bool inline is_shared_readwrite(const void* p) {
2062N/A return p >= readwrite_bottom && p < readwrite_end;
0N/A }
0N/A
2062N/A // Checks if the pointer is either in unshared space or in shared space
0N/A inline bool is_in(const void* p) const {
2062N/A return OneContigSpaceCardGeneration::is_in(p) || is_shared(p);
0N/A }
0N/A
0N/A inline PermanentGenerationSpec* spec() const { return _spec; }
0N/A inline void set_spec(PermanentGenerationSpec* spec) { _spec = spec; }
0N/A
0N/A void pre_adjust_pointers();
0N/A void adjust_pointers();
0N/A void space_iterate(SpaceClosure* blk, bool usedOnly = false);
0N/A void print_on(outputStream* st) const;
0N/A void younger_refs_iterate(OopsInGenClosure* blk);
0N/A void compact();
0N/A void post_compact();
0N/A size_t contiguous_available() const;
0N/A
0N/A void clear_remembered_set();
0N/A void invalidate_remembered_set();
0N/A
0N/A inline bool block_is_obj(const HeapWord* addr) const {
0N/A if (addr < the_space()->top()) return true;
0N/A else if (addr < the_space()->end()) return false;
0N/A else if (addr < ro_space()->top()) return true;
0N/A else if (addr < ro_space()->end()) return false;
0N/A else if (addr < rw_space()->top()) return true;
0N/A else return false;
0N/A }
0N/A
0N/A
0N/A inline size_t block_size(const HeapWord* addr) const {
0N/A if (addr < the_space()->top()) {
0N/A return oop(addr)->size();
0N/A }
0N/A else if (addr < the_space()->end()) {
0N/A assert(addr == the_space()->top(), "non-block head arg to block_size");
0N/A return the_space()->end() - the_space()->top();
0N/A }
0N/A
0N/A else if (addr < ro_space()->top()) {
0N/A return oop(addr)->size();
0N/A }
0N/A else if (addr < ro_space()->end()) {
0N/A assert(addr == ro_space()->top(), "non-block head arg to block_size");
0N/A return ro_space()->end() - ro_space()->top();
0N/A }
0N/A
0N/A else if (addr < rw_space()->top()) {
0N/A return oop(addr)->size();
0N/A }
0N/A else {
0N/A assert(addr == rw_space()->top(), "non-block head arg to block_size");
0N/A return rw_space()->end() - rw_space()->top();
0N/A }
0N/A }
0N/A
0N/A static void generate_vtable_methods(void** vtbl_list,
0N/A void** vtable,
0N/A char** md_top, char* md_end,
0N/A char** mc_top, char* mc_end);
2062N/A static void* find_matching_vtbl_ptr(void** vtbl_list,
2062N/A void* new_vtable_start,
2062N/A void* obj);
0N/A
3679N/A void verify();
0N/A
0N/A // Serialization
4170N/A static void initialize_oops();
0N/A static void serialize_oops(SerializeOopClosure* soc);
0N/A void serialize_bts(SerializeOopClosure* soc);
0N/A
0N/A // Initiate dumping of shared file.
0N/A static jint dump_shared(GrowableArray<oop>* class_promote_order, TRAPS);
0N/A
0N/A // JVM/TI RedefineClasses() support:
0N/A // Remap the shared readonly space to shared readwrite, private if
0N/A // sharing is enabled. Simply returns true if sharing is not enabled
0N/A // or if the remapping has already been done by a prior call.
0N/A static bool remap_shared_readonly_as_readwrite();
0N/A};
1879N/A
1879N/A#endif // SHARE_VM_MEMORY_COMPACTINGPERMGENGEN_HPP