hotspot/src/share/vm/memory/generation.cpp

Print this page
rev 611 : Merge

@@ -1,10 +1,10 @@
 #ifdef USE_PRAGMA_IDENT_SRC
 #pragma ident "@(#)generation.cpp       1.245 07/05/05 17:05:51 JVM"
 #endif
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  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.

@@ -33,10 +33,16 @@
   _ref_processor(NULL) {
   if (!_virtual_space.initialize(rs, initial_size)) {
     vm_exit_during_initialization("Could not reserve enough space for "
                     "object heap");
   }
+  // Mangle all of the the initial generation.
+  if (ZapUnusedHeapArea) {
+    MemRegion mangle_region((HeapWord*)_virtual_space.low(),
+      (HeapWord*)_virtual_space.high());
+    SpaceMangler::mangle_region(mangle_region);
+  }
   _reserved = MemRegion((HeapWord*)_virtual_space.low_boundary(),
           (HeapWord*)_virtual_space.high_boundary());
 }
 
 GenerationSpec* Generation::spec() {

@@ -172,11 +178,11 @@
   }
   return max_contiguous_available() >= promotion_in_bytes;
 }
 
 // Ignores "ref" and calls allocate().
-oop Generation::promote(oop obj, size_t obj_size, oop* ref) {
+oop Generation::promote(oop obj, size_t obj_size) {
   assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
 
 #ifndef PRODUCT
   if (Universe::heap()->promotion_should_fail()) {
     return NULL;

@@ -187,11 +193,11 @@
   if (result != NULL) {
     Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size);
     return oop(result);
   } else {
     GenCollectedHeap* gch = GenCollectedHeap::heap();
-    return gch->handle_failed_promotion(this, obj, obj_size, ref);
+    return gch->handle_failed_promotion(this, obj, obj_size);
   }
 }
 
 oop Generation::par_promote(int thread_num,
                             oop obj, markOop m, size_t word_sz) {

@@ -374,10 +380,45 @@
     // the end if we try.
     guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned");
   }
 }
 
+bool CardGeneration::expand(size_t bytes, size_t expand_bytes) {
+  assert_locked_or_safepoint(Heap_lock);
+  if (bytes == 0) {
+    return true;  // That's what grow_by(0) would return
+  }
+  size_t aligned_bytes  = ReservedSpace::page_align_size_up(bytes);
+  if (aligned_bytes == 0){
+    // The alignment caused the number of bytes to wrap.  An expand_by(0) will
+    // return true with the implication that an expansion was done when it
+    // was not.  A call to expand implies a best effort to expand by "bytes"
+    // but not a guarantee.  Align down to give a best effort.  This is likely
+    // the most that the generation can expand since it has some capacity to
+    // start with.
+    aligned_bytes = ReservedSpace::page_align_size_down(bytes);
+  }
+  size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
+  bool success = false;
+  if (aligned_expand_bytes > aligned_bytes) {
+    success = grow_by(aligned_expand_bytes);
+  }
+  if (!success) {
+    success = grow_by(aligned_bytes);
+  }
+  if (!success) {
+    success = grow_to_reserved();
+  }
+  if (PrintGC && Verbose) {
+    if (success && GC_locker::is_active()) {
+      gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
+    }
+  }
+
+  return success;
+}
+
 
 // No young generation references, clear this generation's cards.
 void CardGeneration::clear_remembered_set() {
   _rs->clear(reserved());
 }

@@ -436,29 +477,13 @@
     expand(word_size*HeapWordSize, _min_heap_delta_bytes);
     return _the_space->allocate(word_size);
   }
 }
 
-void OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) {
+bool OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) {
   GCMutexLocker x(ExpandHeap_lock);
-  size_t aligned_bytes  = ReservedSpace::page_align_size_up(bytes);
-  size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
-  bool success = false;
-  if (aligned_expand_bytes > aligned_bytes) {
-    success = grow_by(aligned_expand_bytes);
-  }
-  if (!success) {
-    success = grow_by(aligned_bytes);
-  }
-  if (!success) {
-    grow_to_reserved();
-  }
-  if (GC_locker::is_active()) {
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
-    }
-  }
+  return CardGeneration::expand(bytes, expand_bytes);
 }
 
 
 void OneContigSpaceCardGeneration::shrink(size_t bytes) {
   assert_locked_or_safepoint(ExpandHeap_lock);

@@ -506,12 +531,15 @@
     Universe::heap()->barrier_set()->resize_covered_region(mr);
     // Expand shared block offset array
     _bts->resize(new_word_size);
 
     // Fix for bug #4668531
-    MemRegion mangle_region(_the_space->end(), (HeapWord*)_virtual_space.high());
-    _the_space->mangle_region(mangle_region);
+    if (ZapUnusedHeapArea) {
+      MemRegion mangle_region(_the_space->end(),
+      (HeapWord*)_virtual_space.high());
+      SpaceMangler::mangle_region(mangle_region);
+    }
 
     // Expand space -- also expands space's BOT
     // (which uses (part of) shared array above)
     _the_space->set_end((HeapWord*)_virtual_space.high());
 

@@ -623,10 +651,18 @@
 void OneContigSpaceCardGeneration::gc_epilogue(bool full) {
   _last_gc = WaterMark(the_space(), the_space()->top());
 
   // update the generation and space performance counters
   update_counters();
+  if (ZapUnusedHeapArea) {
+    the_space()->check_mangled_unused_area_complete();
+  }
+}
+
+void OneContigSpaceCardGeneration::record_spaces_top() {
+  assert(ZapUnusedHeapArea, "Not mangling unused space");
+  the_space()->set_top_for_allocations();
 }
 
 void OneContigSpaceCardGeneration::verify(bool allow_dirty) {
   the_space()->verify(allow_dirty);
 }