space.cpp revision 517
4823N/A * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 4823N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4823N/A * This code is free software; you can redistribute it and/or modify it 4823N/A * under the terms of the GNU General Public License version 2 only, as 4823N/A * published by the Free Software Foundation. 4823N/A * This code is distributed in the hope that it will be useful, but WITHOUT 4823N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4823N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4823N/A * version 2 for more details (a copy is included in the LICENSE file that 4823N/A * You should have received a copy of the GNU General Public License version 4823N/A * 2 along with this work; if not, write to the Free Software Foundation, 4823N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4823N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 4823N/A * CA 95054 USA or visit www.sun.com if you need additional information or 4823N/A#
include "incls/_precompiled.incl" 4823N/A // An arrayOop is starting on the dirty card - since we do exact 4823N/A // store checks for objArrays we are done. 4823N/A // Otherwise, it is possible that the object starting on the dirty 4823N/A // card spans the entire card, and that the store happened on a 4823N/A // later card. Figure out where the object ends. 4823N/A // Use the block_size() method of the space over which 4823N/A // the iteration is being done. That space (e.g. CMS) may have 4823N/A // specific requirements on object sizes which will 4823N/A // be reflected in the block_size() method. // 1. Blocks may or may not be objects. // 2. Even when a block_is_obj(), it may not entirely // occupy the block if the block quantum is larger than // We can and should try to optimize by calling the non-MemRegion // version of oop_iterate() for all but the extremal objects // (for which we need to call the MemRegion version of // oop_iterate()) To be done post-beta XXX // As in the case of contiguous space above, we'd like to // just use the value returned by oop_iterate to increment the // current pointer; unfortunately, that won't work in CMS because // we'd need an interface change (it seems) to have the space // "adjust the object size" (for instance pad it up to its // block alignment or minimum block size restrictions. XXX // Some collectors need to do special things whenever their dirty // cards are processed. For instance, CMS must remember mutator updates // (i.e. dirty cards) so as to re-scan mutated objects. // Such work can be piggy-backed here on dirty card scanning, so as to make // it slightly more efficient than doing a complete non-detructive pre-scan "Only ones we deal with for now.");
// Given what we think is the top of the memory region and // the start of the object at the top, get the actual // If the previous call did some part of this region, don't redo. // Top may have been reset, and in fact may be below bottom, // e.g. the dirty card region is entirely in a now free object // -- something that could happen with a concurrent sweeper. // Walk the region if it is not empty; otherwise there is nothing to do. // An idempotent closure might be applied in any order, so we don't // record a _min_done for it. "Don't update _min_done for idempotent cl");
// An arrayOop is starting on the dirty card - since we do exact // store checks for objArrays we are done. // Otherwise, it is possible that the object starting on the dirty // card spans the entire card, and that the store happened on a // later card. Figure out where the object ends. "Block size and object size mismatch");
// Note that this assumption won't hold if we have a concurrent // collector in this space, which may have freed up objects after // they were dirtied and before the stop-the-world GC that is // We have a boundary outside of which we don't want to look // at objects, so create a filtering closure around the // oop closure before walking the region. // No boundary, simply walk the heap with the oop closure. // We must replicate this so that the static type of "FilteringClosure" // (see above) is apparent at the oop_iterate calls. /* Bottom lies entirely below top, so we can call the */ \
/* non-memRegion version of oop_iterate below. */ \
// (There are only two of these, rather than N, because the split is due // only to the introduction of the FilteringClosure, a local part of the // impl of this abstraction.) "invalid space boundaries");
// Space should not advertize an increase in size // until after the underlying offest table has been enlarged. // Mangled only the unused space that has not previously // been mangled and that has not been allocated since being // Although this method uses SpaceMangler::mangle_region() which // is not specific to a space, the when the ContiguousSpace version // is called, it is always with regard to a space and this // bounds checking is appropriate. // First check if we should switch compaction space assert(
this ==
cp->
space,
"'this' should be current compaction space.");
// switch to next compaction space // store the forwarding pointer into the mark word // if the object isn't moving we can just set the mark to the default // mark and handle it specially later on. // we need to update the offset table so that the beginnings of objects can be // found during scavenge. Note that we are updating the offset table based on // where the object will be once the compaction phase finishes. // Recall that we required "q == compaction_top". // adjust all the interior pointers to point at the new locations of objects // Used by MarkSweep::mark_sweep_phase3() // First check to see if there is any work to be done. return;
// Nothing to do. // point all the oops to the new location // q is not a live object. But we're not in a compactible space, // So we don't have live ranges. assert(q >
prev_q,
"we should be moving forward through memory");
assert(q == t,
"just checking");
// Check first is there is any work to do. return;
// Nothing to do. guarantee(p ==
top(),
"end of last object must match end of space");
"top should be start of unallocated block, if it exists");
// We use MemRegion(bottom(), end()) rather than used_region() below // because the two are not necessarily equal for some kinds of // spaces, in particular, certain kinds of free list spaces. // We could use the more complicated but more precise: // MemRegion(used_region().start(), round_to(used_region().end(), CardSize)) // but the slight imprecision seems acceptable in the assertion check. "Should be within used space");
// This assert will not work when we go from cms space to perm // space, and use same closure. Easy fix deferred for later. XXX YSR // assert(prev == NULL || contains(prev), "Should be within space"); "Should be within (closed) used space");
// See comment above (in more general method above) in case you // happen to use this method. "Should be within (closed) used space");
// Could call objects iterate, but this is easier. // Handle first object specially. // If "obj_addr" is not greater than top, then the // entire object "obj" is within the region. // "obj" extends beyond end of region // For a continguous space object_iterate() and safe_object_iterate() // Very general, slow implementation. // This version requires locking. // This version is lock-free. // result can be one of two: // the old top value: the exchange succeeded // otherwise: the new value of the top is returned. // allocate temporary type array decreasing free size with factor 'factor' // if space is full, return // allocate uninitialized int array "size for smallest fake object doesn't match");
// The invariant is top() should be read before end() because // top() can't be greater than end(), so if an update of _soft_end // occurs between 'end_val = end();' and 'top_val = top();' top() // also can grow up to the new end() and the condition // 'top_val > end_val' is true. To ensure the loading order // OrderAccess::loadload() is required after top() read. // result can be one of two: // the old top value: the exchange succeeded // otherwise: the new value of the top is returned. // For a sampling of objects in the space, find it using the "check offset computation");
guarantee(p ==
top(),
"end of last object must match end of space");