changeset 2472:b099aaf51bf8

6962931: move interned strings out of the perm gen Reviewed-by: never, coleenp, ysr, jwilhelm
author jcoomes
date Tue, 22 Mar 2011 13:36:33 -0700
parents 924777755fad
children 32f7097f9d8f
files src/share/vm/classfile/javaClasses.cpp src/share/vm/classfile/symbolTable.cpp src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp src/share/vm/memory/dump.cpp src/share/vm/memory/sharedHeap.cpp src/share/vm/oops/constantPoolKlass.cpp src/share/vm/opto/library_call.cpp src/share/vm/opto/memnode.cpp src/share/vm/opto/stringopts.cpp src/share/vm/opto/type.hpp src/share/vm/runtime/globals.hpp
diffstat 14 files changed, 58 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/classfile/javaClasses.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/classfile/javaClasses.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -162,7 +162,7 @@
 }
 
 Handle java_lang_String::create_tenured_from_unicode(jchar* unicode, int length, TRAPS) {
-  return basic_create_from_unicode(unicode, length, true, CHECK_NH);
+  return basic_create_from_unicode(unicode, length, JavaObjectsInPerm, CHECK_NH);
 }
 
 oop java_lang_String::create_oop_from_unicode(jchar* unicode, int length, TRAPS) {
--- a/src/share/vm/classfile/symbolTable.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/classfile/symbolTable.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -530,7 +530,7 @@
 
   Handle string;
   // try to reuse the string if possible
-  if (!string_or_null.is_null() && string_or_null()->is_perm()) {
+  if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) {
     string = string_or_null;
   } else {
     string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL);
@@ -662,7 +662,7 @@
     for ( ; p != NULL; p = p->next()) {
       oop s = p->literal();
       guarantee(s != NULL, "interned string is NULL");
-      guarantee(s->is_perm(), "interned string not in permspace");
+      guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
 
       int length;
       jchar* chars = java_lang_String::as_unicode_string(s, length);
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -5930,14 +5930,18 @@
     }
 
     {
-      TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
-      // Now clean up stale oops in StringTable
-      StringTable::unlink(&_is_alive_closure);
+      TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty);
       // Clean up unreferenced symbols in symbol table.
       SymbolTable::unlink();
     }
   }
 
+  if (should_unload_classes() || !JavaObjectsInPerm) {
+    TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty);
+    // Now clean up stale oops in StringTable
+    StringTable::unlink(&_is_alive_closure);
+  }
+
   verify_work_stacks_empty();
   // Restore any preserved marks as a result of mark stack or
   // work queue overflow
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/symbolTable.hpp"
 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
 #include "gc_implementation/parallelScavenge/generationSizer.hpp"
@@ -439,6 +440,14 @@
       reference_processor()->enqueue_discovered_references(NULL);
     }
 
+    if (!JavaObjectsInPerm) {
+      // Unlink any dead interned Strings
+      StringTable::unlink(&_is_alive_closure);
+      // Process the remaining live ones
+      PSScavengeRootsClosure root_closure(promotion_manager);
+      StringTable::oops_do(&root_closure);
+    }
+
     // Finally, flush the promotion_manager's labs, and deallocate its stacks.
     PSPromotionManager::post_scavenge();
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	Tue Mar 22 13:36:33 2011 -0700
@@ -86,4 +86,21 @@
   }
 }
 
+class PSScavengeRootsClosure: public OopClosure {
+ private:
+  PSPromotionManager* _promotion_manager;
+
+ protected:
+  template <class T> void do_oop_work(T *p) {
+    if (PSScavenge::should_scavenge(p)) {
+      // We never card mark roots, maybe call a func without test?
+      PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
+    }
+  }
+ public:
+  PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
+  void do_oop(oop* p)       { PSScavengeRootsClosure::do_oop_work(p); }
+  void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); }
+};
+
 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSSCAVENGE_INLINE_HPP
--- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -30,7 +30,7 @@
 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.hpp"
+#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
 #include "gc_implementation/parallelScavenge/psTasks.hpp"
 #include "memory/iterator.hpp"
 #include "memory/universe.hpp"
@@ -46,24 +46,6 @@
 // ScavengeRootsTask
 //
 
-// Define before use
-class PSScavengeRootsClosure: public OopClosure {
- private:
-  PSPromotionManager* _promotion_manager;
-
- protected:
-  template <class T> void do_oop_work(T *p) {
-    if (PSScavenge::should_scavenge(p)) {
-      // We never card mark roots, maybe call a func without test?
-      PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
-    }
-  }
- public:
-  PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
-  void do_oop(oop* p)       { PSScavengeRootsClosure::do_oop_work(p); }
-  void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); }
-};
-
 void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
   assert(Universe::heap()->is_gc_active(), "called outside gc");
 
--- a/src/share/vm/memory/dump.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/memory/dump.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -1561,6 +1561,7 @@
     // thread because it requires object allocation.
     LinkClassesClosure lcc(Thread::current());
     object_iterate(&lcc);
+    ensure_parsability(false); // arg is actually don't care
     tty->print_cr("done. ");
 
     // Create and dump the shared spaces.
--- a/src/share/vm/memory/sharedHeap.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/memory/sharedHeap.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -171,11 +171,13 @@
   }
 
   if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
-     if (so & SO_Strings) {
-       StringTable::oops_do(roots);
-     }
-    // Verify if the string table contents are in the perm gen
-    NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
+    if (so & SO_Strings || (!collecting_perm_gen && !JavaObjectsInPerm)) {
+      StringTable::oops_do(roots);
+    }
+    if (JavaObjectsInPerm) {
+      // Verify the string table contents are in the perm gen
+      NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
+    }
   }
 
   if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
--- a/src/share/vm/oops/constantPoolKlass.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/oops/constantPoolKlass.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -285,10 +285,11 @@
 void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   assert(obj->is_constantPool(), "should be constant pool");
   constantPoolOop cp = (constantPoolOop) obj;
-  if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
-    oop* base = (oop*)cp->base();
-    for (int i = 0; i < cp->length(); ++i, ++base) {
+  if (cp->tags() != NULL &&
+      (!JavaObjectsInPerm || (AnonymousClasses && cp->has_pseudo_string()))) {
+    for (int i = 1; i < cp->length(); ++i) {
       if (cp->tag_at(i).is_string()) {
+        oop* base = cp->obj_at_addr_raw(i);
         if (PSScavenge::should_scavenge(base)) {
           pm->claim_or_forward_depth(base);
         }
@@ -460,7 +461,8 @@
       if (cp->tag_at(i).is_string()) {
         if (!cp->has_pseudo_string()) {
           if (entry.is_oop()) {
-            guarantee(entry.get_oop()->is_perm(),   "should be in permspace");
+            guarantee(!JavaObjectsInPerm || entry.get_oop()->is_perm(),
+                      "should be in permspace");
             guarantee(entry.get_oop()->is_instance(), "should be instance");
           }
         } else {
--- a/src/share/vm/opto/library_call.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/opto/library_call.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -1116,7 +1116,7 @@
   Node* sourcea       = basic_plus_adr(string_object, string_object, value_offset);
   Node* source        = make_load(no_ctrl, sourcea, source_type, T_OBJECT, string_type->add_offset(value_offset));
 
-  Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array)) );
+  Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)) );
   jint target_length = target_array->length();
   const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
   const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
--- a/src/share/vm/opto/memnode.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/opto/memnode.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -1573,9 +1573,9 @@
             return TypeInt::make(constant.as_int());
           } else if (constant.basic_type() == T_ARRAY) {
             if (adr->bottom_type()->is_ptr_to_narrowoop()) {
-              return TypeNarrowOop::make_from_constant(constant.as_object());
+              return TypeNarrowOop::make_from_constant(constant.as_object(), true);
             } else {
-              return TypeOopPtr::make_from_constant(constant.as_object());
+              return TypeOopPtr::make_from_constant(constant.as_object(), true);
             }
           }
         }
--- a/src/share/vm/opto/stringopts.cpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/opto/stringopts.cpp	Tue Mar 22 13:36:33 2011 -0700
@@ -910,7 +910,7 @@
       ciObject* con = field->constant_value().as_object();
       // Do not "join" in the previous type; it doesn't add value,
       // and may yield a vacuous result if the field is of interface type.
-      type = TypeOopPtr::make_from_constant(con)->isa_oopptr();
+      type = TypeOopPtr::make_from_constant(con, true)->isa_oopptr();
       assert(type != NULL, "field singleton type must be consistent");
     } else {
       type = TypeOopPtr::make_from_klass(field_klass->as_klass());
--- a/src/share/vm/opto/type.hpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/opto/type.hpp	Tue Mar 22 13:36:33 2011 -0700
@@ -988,8 +988,8 @@
 
   static const TypeNarrowOop *make( const TypePtr* type);
 
-  static const TypeNarrowOop* make_from_constant(ciObject* con) {
-    return make(TypeOopPtr::make_from_constant(con));
+  static const TypeNarrowOop* make_from_constant(ciObject* con, bool require_constant = false) {
+    return make(TypeOopPtr::make_from_constant(con, require_constant));
   }
 
   // returns the equivalent ptr type for this compressed pointer
--- a/src/share/vm/runtime/globals.hpp	Mon Mar 21 18:38:00 2011 -0700
+++ b/src/share/vm/runtime/globals.hpp	Tue Mar 22 13:36:33 2011 -0700
@@ -851,7 +851,7 @@
   diagnostic(bool, TraceNMethodInstalls, false,                             \
              "Trace nmethod intallation")                                   \
                                                                             \
-  diagnostic(intx, ScavengeRootsInCode, 0,                                  \
+  diagnostic(intx, ScavengeRootsInCode, 1,                                  \
              "0: do not allow scavengable oops in the code cache; "         \
              "1: allow scavenging from the code cache; "                    \
              "2: emit as many constants as the compiler can see")           \