diff src/share/vm/gc_implementation/shared/vmGCOperations.cpp @ 6948:e522a00b91aa

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author Doug Simon <doug.simon@oracle.com>
date Mon, 12 Nov 2012 23:14:12 +0100
parents 097d78aaf2b5
children 16fb9f942703 db9981fd3124
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Mon Nov 12 18:11:17 2012 +0100
+++ b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Mon Nov 12 23:14:12 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -70,13 +70,13 @@
 
 void VM_GC_Operation::acquire_pending_list_lock() {
   // we may enter this with pending exception set
-  instanceRefKlass::acquire_pending_list_lock(&_pending_list_basic_lock);
+  InstanceRefKlass::acquire_pending_list_lock(&_pending_list_basic_lock);
 }
 
 
 void VM_GC_Operation::release_and_notify_pending_list_lock() {
 
-  instanceRefKlass::release_and_notify_pending_list_lock(&_pending_list_basic_lock);
+  InstanceRefKlass::release_and_notify_pending_list_lock(&_pending_list_basic_lock);
 }
 
 // Allocations may fail in several threads at about the same time,
@@ -192,31 +192,55 @@
   gch->do_full_collection(gch->must_clear_all_soft_refs(), _max_level);
 }
 
-void VM_GenCollectForPermanentAllocation::doit() {
+void VM_CollectForMetadataAllocation::doit() {
   SvcGCMarker sgcm(SvcGCMarker::FULL);
 
-  SharedHeap* heap = (SharedHeap*)Universe::heap();
+  CollectedHeap* heap = Universe::heap();
   GCCauseSetter gccs(heap, _gc_cause);
-  switch (heap->kind()) {
-    case (CollectedHeap::GenCollectedHeap): {
-      GenCollectedHeap* gch = (GenCollectedHeap*)heap;
-      gch->do_full_collection(gch->must_clear_all_soft_refs(),
-                              gch->n_gens() - 1);
-      break;
+
+  // Check again if the space is available.  Another thread
+  // may have similarly failed a metadata allocation and induced
+  // a GC that freed space for the allocation.
+  if (!MetadataAllocationFailALot) {
+    _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
+    }
+
+  if (_result == NULL) {
+    if (UseConcMarkSweepGC) {
+      if (CMSClassUnloadingEnabled) {
+        MetaspaceGC::set_should_concurrent_collect(true);
+      }
+      // For CMS expand since the collection is going to be concurrent.
+      _result =
+        _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
     }
-#ifndef SERIALGC
-    case (CollectedHeap::G1CollectedHeap): {
-      G1CollectedHeap* g1h = (G1CollectedHeap*)heap;
-      g1h->do_full_collection(_gc_cause == GCCause::_last_ditch_collection);
-      break;
+    if (_result == NULL) {
+      // Don't clear the soft refs.  This GC is for reclaiming metadata
+      // and is unrelated to the fullness of the Java heap which should
+      // be the criteria for clearing SoftReferences.
+      if (Verbose && PrintGCDetails && UseConcMarkSweepGC) {
+        gclog_or_tty->print_cr("\nCMS full GC for Metaspace");
+      }
+      heap->collect_as_vm_thread(GCCause::_metadata_GC_threshold);
+      _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
     }
-#endif // SERIALGC
-    default:
-      ShouldNotReachHere();
+    if (_result == NULL && !UseConcMarkSweepGC /* CMS already tried */) {
+      // If still failing, allow the Metaspace to expand.
+      // See delta_capacity_until_GC() for explanation of the
+      // amount of the expansion.
+      // This should work unless there really is no more space
+      // or a MaxMetaspaceSize has been specified on the command line.
+      _result =
+        _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
+
+    }
+    if (Verbose && PrintGCDetails && _result == NULL) {
+      gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size "
+                             SIZE_FORMAT, _size);
+    }
   }
-  _res = heap->perm_gen()->allocate(_size, false);
-  assert(heap->is_in_reserved_or_null(_res), "result not in heap");
-  if (_res == NULL && GC_locker::is_active_and_needs_gc()) {
+
+  if (_result == NULL && GC_locker::is_active_and_needs_gc()) {
     set_gc_locked();
   }
 }