/* * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// A space is an abstraction for the "storage units" backing // up the generation abstraction. It includes specific // implementations for keeping track of free and used space, // for iterating over objects and free blocks, etc.
// Forward decls. class Space; class ContiguousSpace; #if INCLUDE_SERIALGC class BlockOffsetArray; class BlockOffsetArrayContigSpace; class BlockOffsetTable; #endif class Generation; class CompactibleSpace; class CardTableRS; class DirtyCardToOopClosure; class FilteringClosure;
// A Space describes a heap area. Class Space is an abstract // base class. // // Space supports allocation, size computation and GC support is provided. // // Invariant: bottom() and end() are on page_size boundaries and // bottom() <= top() <= end() // top() is inclusive and end() is exclusive.
class Space: public CHeapObj<mtGC> { friendclass VMStructs; protected:
HeapWord* _bottom;
HeapWord* _end;
// Used in support of save_marks()
HeapWord* _saved_mark_word;
// Returns true if this object has been allocated since a // generation's "save_marks" call. virtualbool obj_allocated_since_save_marks(const oop obj) const { return cast_from_oop<HeapWord*>(obj) >= saved_mark_word();
}
// Returns a subregion of the space containing only the allocated objects in // the space. virtual MemRegion used_region() const = 0;
// Returns a region that is guaranteed to contain (at least) all objects // allocated at the time of the last call to "save_marks". If the space // initializes its DirtyCardToOopClosure's specifying the "contig" option // (that is, if the space is contiguous), then this region must contain only // such objects: the memregion will be from the bottom of the region to the // saved mark. Otherwise, the "obj_allocated_since_save_marks" method of // the space must distinguish between objects in the region allocated before // and after the call to save marks.
MemRegion used_region_at_save_marks() const { return MemRegion(bottom(), saved_mark_word());
}
// Initialization. // "initialize" should be called once on a space, before it is used for // any purpose. The "mr" arguments gives the bounds of the space, and // the "clear_space" argument should be true unless the memory in "mr" is // known to be zeroed. virtualvoid initialize(MemRegion mr, bool clear_space, bool mangle_space);
// The "clear" method must be called on a region that may have // had allocation performed in it, but is now to be considered empty. virtualvoid clear(bool mangle_space);
// For detecting GC bugs. Should only be called at GC boundaries, since // some unused space may be used as scratch space during GC's. // We also call this when expanding a space to satisfy an allocation // request. See bug #4668531 virtualvoid mangle_unused_area() = 0; virtualvoid mangle_unused_area_complete() = 0;
// Returns true iff the given the space contains the // given address as part of an allocated object. For // certain kinds of spaces, this might be a potentially // expensive operation. To prevent performance problems // on account of its inadvertent use in product jvm's, // we restrict its use to assertion checks only. bool is_in(constvoid* p) const { return used_region().contains(p);
} bool is_in(oop obj) const { return is_in((void*)obj);
}
// Returns true iff the given reserved memory of the space contains the // given address. bool is_in_reserved(constvoid* p) const { return _bottom <= p && p < _end; }
// Returns true iff the given block is not allocated. virtualbool is_free_block(const HeapWord* p) const = 0;
// Test whether p is double-aligned staticbool is_aligned(void* p) { return ::is_aligned(p, sizeof(double));
}
// Iterate over all the ref-containing fields of all objects in the // space, calling "cl.do_oop" on each. Fields in objects allocated by // applications of the closure are not included in the iteration. virtualvoid oop_iterate(OopIterateClosure* cl);
// Iterate over all objects in the space, calling "cl.do_object" on // each. Objects allocated by applications of the closure are not // included in the iteration. virtualvoid object_iterate(ObjectClosure* blk) = 0;
// Create and return a new dirty card to oop closure. Can be // overridden to return the appropriate type of closure // depending on the type of space in which the closure will // operate. ResourceArea allocated. virtual DirtyCardToOopClosure* new_dcto_cl(OopIterateClosure* cl,
CardTable::PrecisionStyle precision,
HeapWord* boundary);
// If "p" is in the space, returns the address of the start of the // "block" that contains "p". We say "block" instead of "object" since // some heaps may not pack objects densely; a chunk may either be an // object or a non-object. If "p" is not in the space, return NULL. virtual HeapWord* block_start_const(constvoid* p) const = 0;
// The non-const version may have benevolent side effects on the data // structure supporting these calls, possibly speeding up future calls. // The default implementation, however, is simply to call the const // version. virtual HeapWord* block_start(constvoid* p);
// Requires "addr" to be the start of a chunk, and returns its size. // "addr + size" is required to be the start of a new chunk, or the end // of the active area of the heap. virtual size_t block_size(const HeapWord* addr) const = 0;
// Requires "addr" to be the start of a block, and returns "TRUE" iff // the block is an object. virtualbool block_is_obj(const HeapWord* addr) const = 0;
// Requires "addr" to be the start of a block, and returns "TRUE" iff // the block is an object and the object is alive. virtualbool obj_is_alive(const HeapWord* addr) const;
// Allocation (return NULL if full). Assumes the caller has established // mutually exclusive access to the space. virtual HeapWord* allocate(size_t word_size) = 0;
#if INCLUDE_SERIALGC // Mark-sweep-compact support: all spaces can update pointers to objects // moving as a part of compaction. virtualvoid adjust_pointers() = 0; #endif
// IF "this" is a ContiguousSpace, return it, else return NULL. virtual ContiguousSpace* toContiguousSpace() { return NULL;
}
// Debugging virtualvoid verify() const = 0;
};
// A MemRegionClosure (ResourceObj) whose "do_MemRegion" function applies an // OopClosure to (the addresses of) all the ref-containing fields that could // be modified by virtue of the given MemRegion being dirty. (Note that // because of the imprecise nature of the write barrier, this may iterate // over oops beyond the region.) // This base type for dirty card to oop closures handles memory regions // in non-contiguous spaces with no boundaries, and should be sub-classed // to support other space types. See ContiguousDCTOC for a sub-class // that works with ContiguousSpaces.
class DirtyCardToOopClosure: public MemRegionClosureRO { protected:
OopIterateClosure* _cl;
Space* _sp;
CardTable::PrecisionStyle _precision;
HeapWord* _boundary; // If non-NULL, process only non-NULL oops // pointing below boundary.
HeapWord* _min_done; // ObjHeadPreciseArray precision requires // a downwards traversal; this is the // lowest location already done (or, // alternatively, the lowest address that // shouldn't be done again. NULL means infinity.)
NOT_PRODUCT(HeapWord* _last_bottom;)
// Get the actual top of the area on which the closure will // operate, given where the top is assumed to be (the end of the // memory region passed to do_MemRegion) and where the object // at the top is assumed to start. For example, an object may // start at the top but actually extend past the assumed top, // in which case the top becomes the end of the object. virtual HeapWord* get_actual_top(HeapWord* top, HeapWord* top_obj);
// Walk the given memory region from bottom to (actual) top // looking for objects and applying the oop closure (_cl) to // them. The base implementation of this treats the area as // blocks, where a block may or may not be an object. Sub- // classes should override this to provide more accurate // or possibly more efficient walking. virtualvoid walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top);
// A structure to represent a point at which objects are being copied // during compaction. class CompactPoint : public StackObj { public:
Generation* gen;
CompactibleSpace* space;
CompactPoint(Generation* g = NULL) :
gen(g), space(NULL) {}
};
// A space that supports compaction operations. This is usually, but not // necessarily, a space that is normally contiguous. But, for example, a // free-list-based space whose normal collection is a mark-sweep without // compaction could still support compaction in full GC's. class CompactibleSpace: public Space { friendclass VMStructs; private:
HeapWord* _compaction_top;
CompactibleSpace* _next_compaction_space;
// Used temporarily during a compaction phase to hold the value // top should have when compaction is complete.
HeapWord* compaction_top() const { return _compaction_top; }
// Perform operations on the space needed after a compaction // has been performed. virtualvoid reset_after_compaction() = 0;
// Returns the next space (in the current generation) to be compacted in // the global compaction order. Also is used to select the next // space into which to compact.
// Start the process of compaction of the current space: compute // post-compaction addresses, and insert forwarding pointers. The fields // "cp->gen" and "cp->compaction_space" are the generation and space into // which we are currently compacting. This call updates "cp" as necessary, // and leaves the "compaction_top" of the final value of // "cp->compaction_space" up-to-date. Offset tables may be updated in // this phase as if the final copy had occurred; if so, "cp->threshold" // indicates when the next such action should be taken. virtualvoid prepare_for_compaction(CompactPoint* cp) = 0; // MarkSweep support phase3 void adjust_pointers() override; // MarkSweep support phase4 virtualvoid compact(); #endif// INCLUDE_SERIALGC
// The maximum percentage of objects that can be dead in the compacted // live part of a compacted space ("deadwood" support.) virtual size_t allowed_dead_ratio() const { return 0; };
// Some contiguous spaces may maintain some data structures that should // be updated whenever an allocation crosses a boundary. This function // initializes these data structures for further updates. virtualvoid initialize_threshold() { }
// "q" is an object of the given "size" that should be forwarded; // "cp" names the generation ("gen") and containing "this" (which must // also equal "cp->space"). "compact_top" is where in "this" the // next object should be forwarded to. If there is room in "this" for // the object, insert an appropriate forwarding pointer in "q". // If not, go to the next compaction space (there must // be one, since compaction must succeed -- we go to the first space of // the previous generation if necessary, updating "cp"), reset compact_top // and then forward. In either case, returns the new value of "compact_top". // Invokes the "alloc_block" function of the then-current compaction // space. virtual HeapWord* forward(oop q, size_t size, CompactPoint* cp,
HeapWord* compact_top); protected: // Used during compaction.
HeapWord* _first_dead;
HeapWord* _end_of_live;
// This the function to invoke when an allocation of an object covering // "start" to "end" occurs to update other internal data structures. virtualvoid alloc_block(HeapWord* start, HeapWord* the_end) { }
};
class GenSpaceMangler;
// A space in which the free area is contiguous. It therefore supports // faster allocation, and compaction. class ContiguousSpace: public CompactibleSpace { friendclass VMStructs;
protected:
HeapWord* _top; // A helper for mangling the unused area of the space in debug builds.
GenSpaceMangler* _mangler;
// In debug mode mangle (write it with a particular bit // pattern) the unused part of a space.
// Used to save the address in a space for later use during mangling. void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN; // Used to save the space's current top for later use during mangling. void set_top_for_allocations() PRODUCT_RETURN;
// Mangle regions in the space from the current top up to the // previously mangled part of the space. void mangle_unused_area() override PRODUCT_RETURN; // Mangle [top, end) void mangle_unused_area_complete() override PRODUCT_RETURN;
// Do some sparse checking on the area that should have been mangled. void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; // Check the complete area that should have been mangled. // This code may be NULL depending on the macro DEBUG_MANGLING. void check_mangled_unused_area_complete() PRODUCT_RETURN;
// In a contiguous space we have a more obvious bound on what parts // contain objects.
MemRegion used_region() const override { return MemRegion(bottom(), top()); }
// Apply "blk->do_oop" to the addresses of all reference fields in objects // starting with the _saved_mark_word, which was noted during a generation's // save_marks and is required to denote the head of an object. // Fields in objects allocated by applications of the closure // *are* included in the iteration. // Updates _saved_mark_word to point to just after the last object // iterated over. template <typename OopClosureType> void oop_since_save_marks_iterate(OopClosureType* blk);
// Same as object_iterate, but starting from "mark", which is required // to denote the start of an object. Objects allocated by // applications of the closure *are* included in the iteration. virtualvoid object_iterate_from(HeapWord* mark, ObjectClosure* blk);
// Very inefficient implementation.
HeapWord* block_start_const(constvoid* p) const override;
size_t block_size(const HeapWord* p) const override; // If a block is in the allocated area, it is an object. bool block_is_obj(const HeapWord* p) const override { return p < top(); }
// A dirty card to oop closure for contiguous spaces (ContiguousSpace and // sub-classes). It knows how to filter out objects that are outside of the // _boundary. // // Assumptions: // 1. That the actual top of any area in a memory region // contained by the space is bounded by the end of the contiguous // region of the space. // 2. That the space is really made up of objects and not just // blocks. class ContiguousSpaceDCTOC : public DirtyCardToOopClosure { // Overrides. void walk_mem_region(MemRegion mr,
HeapWord* bottom, HeapWord* top) override;
// Walk the given memory region, from bottom to top, applying // the given oop closure to (possibly) all objects found. The // given oop closure may or may not be the same as the oop // closure with which this closure was created, as it may // be a filtering closure which makes use of the _boundary. // We offer two signatures, so the FilteringClosure static type is // apparent. void walk_mem_region_with_cl(MemRegion mr,
HeapWord* bottom, HeapWord* top,
OopIterateClosure* cl); void walk_mem_region_with_cl(MemRegion mr,
HeapWord* bottom, HeapWord* top,
FilteringClosure* cl);
// A ContigSpace that Supports an efficient "block_start" operation via // a BlockOffsetArray (whose BlockOffsetSharedArray may be shared with // other spaces.) This is the abstract base class for old generation // (tenured) spaces.
#if INCLUDE_SERIALGC class OffsetTableContigSpace: public ContiguousSpace { friendclass VMStructs; protected:
BlockOffsetArrayContigSpace _offsets;
Mutex _par_alloc_lock;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.