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