cardTableExtension.cpp revision 3680
2362N/A * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 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 2362N/A * published by the Free Software Foundation. 2362N/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 * 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 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A// Checks an individual oop for missing precise marks. Mark 0N/A// may be either dirty or newgen. 0N/A // Don't overwrite the first missing card mark 0N/A// Checks all objects for the existance of some type of mark, 0N/A// precise or imprecise, dirty or newgen. 0N/A // No point in asserting barrier set type here. Need to make CardTableExtension 0N/A // a unique barrier set type. 0N/A // Card marks are not precise. The current system can leave us with // a mismash of precise marks and beginning of object marks. This means // we test for missing precise marks first. If any are found, we don't // fail unless the object head is also unmarked. // Checks for precise marking of oops as newgen. // We get passed the space_top value to prevent us from traversing into // the old_gen promotion labs, which cannot be safely parsed. "ObjectStartArray does not cover space");
// scan card marking array // we found a non-clean card // find object starting on card // bottom_obj = (oop*)start_array->object_start((HeapWord*)bottom); // make sure we don't scan oops we already looked at // figure out when to stop scanning // check if we reached the end, if so we are done // we have a clean card, find object starting on that card // top_obj = (oop*)start_array->object_start((HeapWord*)top); // an arrayOop is starting on the clean card - since we do exact store // checks for objArrays we are done // otherwise, it is possible that the object starting on the clean card // spans the entire card, and that the store happened on a later card. // figure out where the object ends // object ends a different card // the ending card is clean, we are done // the ending card is not clean, continue scanning at start of do-while // object ends on the clean card, we are done. // we know which cards to scan, now clear them // remember top oop* scanned int ssize =
128;
// Naked constant! Work unit = 64k. // The width of the stripe ssize*stripe_total must be // consistent with the number of stripes so that the complete slice // We do not want to scan objects more than once. In order to accomplish // this, we assert that any object with an object head inside our 'slice' // belongs to us. We may need to extend the range of scanned cards if the // last object continues into the next 'slice'. // Note! ending cards are exclusive! // If there are not objects starting within the chunk, skip it. // Update our beginning addr // Update the ending addr // The subtraction is important! An object may start precisely at slice_end. // worker_end_card is exclusive, so bump it one past the end of last_object's // Note that worker_start_card >= worker_end_card is legal, and happens when // an object spans an entire slice. // Find the end of a run of contiguous unclean cards // Some objects may be large enough to span several cards. If such // an object has more than one dirty card, separated by a clean card, // we will attempt to scan it twice. The test against "last_scanned" // prevents the redundant object scan, but it does not prevent newly // marked cards from being cleaned. // This means the object spans the next complete card. // We need to bump the current_card to ending_card_of_last_object // "p" should always be >= "last_scanned" because newly GC dirtied // cards are no longer scanned again (see comment at end // of loop on the increment of "current_card"). Test that // hypothesis before removing this code. // If this code is removed, deal with the first time through // the loop when the last_scanned is the object starting in "Should no longer be possible");
// Avoid scanning more than once; this can happen because // newgen cards set by GC may a different set than the // we know which cards to scan, now clear them // scan all objects in the range // "current_card" is still the "following_clean_card" or // the current_card is >= the worker_end_card so the // loop will not execute again. "current_card should only be incremented if it still equals " // Increment current_card so that it is not processed again. // It may now be dirty because a old-to-young pointer was // found on it an updated. If it is now dirty, it cannot be // be safely cleaned in the next iteration. // This should be called before a scavenge. // This should be called immediately after a scavenge, before mutators resume. assert(
false,
"Found unhandled card mark type");
// Also includes verify_card assert(
false,
"Found unhandled card mark type");
// Assumes that only the base or the end changes. This allows indentification // of the region that is being resized. The // CardTableModRefBS::resize_covered_region() is used for the normal case // where the covered regions are growing or shrinking at the high end. // The method resize_covered_region_by_end() is analogous to // CardTableModRefBS::resize_covered_region() but // for regions that grow or shrink at the low end. // Found a covered region with the same start as the // new region. The region is growing or shrinking // from the start of the region. // This is a case where the covered region is growing or shrinking // at the start of the region. "The sizes should be different here");
// This should only be a new covered region (where no existing // covered region matches at the start or the end). "An existing region should have been found");
"Only expect an expansion at the low end at a GC");
// Commit new or uncommit old pages, if necessary. // Set the new start of the committed region // Update card table entries // Update the covered region // Commit new or uncommit old pages, if necessary. "The ends of the regions are expected to match");
// Extend the start of this _committed region to // to cover the start of any previous _committed region. // This forms overlapping regions, but never interior regions. // Only really need to set start of "cur_committed" to // the new start (min_prev_start) but assertion checking code // below use cur_committed.end() so make it correct. "Starts should have proper alignment");
// Round down because this is for the start address // The guard page is always committed and should not be committed over. // This method is used in cases where the generation is growing toward // lower addresses but the guard region is still at the end of the // card table. That still makes sense when looking for writes // off the end of the card table. // Expand the committed region // |+ cur committed +++++++++| // |+ new committed +++++++++++++++++| // |+ new committed +++++++| // These are not expected because the calculation of the // cur committed region and the new committed region // share the same end for the covered region. // |+ new committed +++++++++++++++++| // |+ cur committed +++++++++++| // |+ new committed +++++++| // Shrink the committed region #
if 0
// uncommitting space is currently unsafe because of the interactions // of growing and shrinking regions. One region A can uncommit space // that it owns but which is being used by another region B (maybe). // Region B has not committed the space because it was already // committed by region A. // If the uncommit fails, ignore it. Let the // committed table resizing go even though the committed // table will over state the committed space. "end should not change");
// Set the new start of the committed region // Initialize the card entries. Only consider the // region covered by the card table (_whole_heap) // If _whole_heap starts at the original covered regions start, // this loop will not execute. // Update the covered region // reorder regions. There should only be at most 1 out "Covered regions out of order");
"Committed regions out of order");
// Returns the start of any committed region that is lower than // the target committed region (index ind) and that intersects the // target region. If none, return start of target region. for (
int j = 0; j <
ind; j++) {