diff src/share/vm/oops/instanceMirrorKlass.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 aed758eda82a
children db9981fd3124
line wrap: on
line diff
--- a/src/share/vm/oops/instanceMirrorKlass.cpp	Mon Nov 12 18:11:17 2012 +0100
+++ b/src/share/vm/oops/instanceMirrorKlass.cpp	Mon Nov 12 23:14:12 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -29,7 +29,6 @@
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/oopFactory.hpp"
-#include "memory/permGen.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceOop.hpp"
@@ -37,6 +36,7 @@
 #include "oops/symbol.hpp"
 #include "runtime/handles.inline.hpp"
 #ifndef SERIALGC
+#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
@@ -47,7 +47,7 @@
 #include "oops/oop.pcgc.inline.hpp"
 #endif
 
-int instanceMirrorKlass::_offset_of_static_fields = 0;
+int InstanceMirrorKlass::_offset_of_static_fields = 0;
 
 #ifdef ASSERT
 template <class T> void assert_is_in(T *p) {
@@ -148,8 +148,20 @@
 }
 
 
-void instanceMirrorKlass::oop_follow_contents(oop obj) {
-  instanceKlass::oop_follow_contents(obj);
+void InstanceMirrorKlass::oop_follow_contents(oop obj) {
+  InstanceKlass::oop_follow_contents(obj);
+
+  // Follow the klass field in the mirror.
+  Klass* klass = java_lang_Class::as_Klass(obj);
+  if (klass != NULL) {
+    MarkSweep::follow_klass(klass);
+  } else {
+    // If klass is NULL then this a mirror for a primitive type.
+    // We don't have to follow them, since they are handled as strong
+    // roots in Universe::oops_do.
+    assert(java_lang_Class::is_primitive(obj), "Sanity check");
+  }
+
   InstanceMirrorKlass_OOP_ITERATE(                                                    \
     start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
     MarkSweep::mark_and_push(p),                                                      \
@@ -157,9 +169,21 @@
 }
 
 #ifndef SERIALGC
-void instanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm,
+void InstanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm,
                                               oop obj) {
-  instanceKlass::oop_follow_contents(cm, obj);
+  InstanceKlass::oop_follow_contents(cm, obj);
+
+  // Follow the klass field in the mirror.
+  Klass* klass = java_lang_Class::as_Klass(obj);
+  if (klass != NULL) {
+    PSParallelCompact::follow_klass(cm, klass);
+  } else {
+    // If klass is NULL then this a mirror for a primitive type.
+    // We don't have to follow them, since they are handled as strong
+    // roots in Universe::oops_do.
+    assert(java_lang_Class::is_primitive(obj), "Sanity check");
+  }
+
   InstanceMirrorKlass_OOP_ITERATE(                                                    \
     start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
     PSParallelCompact::mark_and_push(cm, p),                                          \
@@ -167,9 +191,21 @@
 }
 #endif // SERIALGC
 
-int instanceMirrorKlass::oop_adjust_pointers(oop obj) {
+int InstanceMirrorKlass::oop_adjust_pointers(oop obj) {
   int size = oop_size(obj);
-  instanceKlass::oop_adjust_pointers(obj);
+  InstanceKlass::oop_adjust_pointers(obj);
+
+  // Follow the klass field in the mirror.
+  Klass* klass = java_lang_Class::as_Klass(obj);
+  if (klass != NULL) {
+    MarkSweep::adjust_klass(klass);
+  } else {
+    // If klass is NULL then this a mirror for a primitive type.
+    // We don't have to follow them, since they are handled as strong
+    // roots in Universe::oops_do.
+    assert(java_lang_Class::is_primitive(obj), "Sanity check");
+  }
+
   InstanceMirrorKlass_OOP_ITERATE(                                                    \
     start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
     MarkSweep::adjust_pointer(p),                                                     \
@@ -193,17 +229,31 @@
   return oop_size(obj);                                                               \
 
 
-// Macro to define instanceMirrorKlass::oop_oop_iterate for virtual/nonvirtual for
+#define if_do_metadata_checked(closure, nv_suffix)                    \
+  /* Make sure the non-virtual and the virtual versions match. */     \
+  assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
+      "Inconsistency in do_metadata");                                \
+  if (closure->do_metadata##nv_suffix())
+
+// Macro to define InstanceMirrorKlass::oop_oop_iterate for virtual/nonvirtual for
 // all closures.  Macros calling macros above for each oop size.
 
 #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)           \
                                                                                       \
-int instanceMirrorKlass::                                                             \
+int InstanceMirrorKlass::                                                             \
 oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                        \
   /* Get size before changing pointers */                                             \
   SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
                                                                                       \
-  instanceKlass::oop_oop_iterate##nv_suffix(obj, closure);                            \
+  InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);                            \
+                                                                                      \
+  if_do_metadata_checked(closure, nv_suffix) {                                        \
+    Klass* klass = java_lang_Class::as_Klass(obj);                                    \
+    /* We'll get NULL for primitive mirrors. */                                       \
+    if (klass != NULL) {                                                              \
+      closure->do_klass##nv_suffix(klass);                                            \
+    }                                                                                 \
+  }                                                                                   \
                                                                                       \
   if (UseCompressedOops) {                                                            \
     InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix);           \
@@ -215,12 +265,12 @@
 #ifndef SERIALGC
 #define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
                                                                                       \
-int instanceMirrorKlass::                                                             \
+int InstanceMirrorKlass::                                                             \
 oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {              \
   /* Get size before changing pointers */                                             \
   SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
                                                                                       \
-  instanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure);                  \
+  InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure);                  \
                                                                                       \
   if (UseCompressedOops) {                                                            \
     InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix);           \
@@ -233,13 +283,24 @@
 
 #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)         \
                                                                                       \
-int instanceMirrorKlass::                                                             \
+int InstanceMirrorKlass::                                                             \
 oop_oop_iterate##nv_suffix##_m(oop obj,                                               \
                                OopClosureType* closure,                               \
                                MemRegion mr) {                                        \
   SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
                                                                                       \
-  instanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);                    \
+  InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);                    \
+                                                                                      \
+  if_do_metadata_checked(closure, nv_suffix) {                                        \
+    if (mr.contains(obj)) {                                                           \
+      Klass* klass = java_lang_Class::as_Klass(obj);                                  \
+      /* We'll get NULL for primitive mirrors. */                                     \
+      if (klass != NULL) {                                                            \
+        closure->do_klass##nv_suffix(klass);                                          \
+      }                                                                               \
+    }                                                                                 \
+  }                                                                                   \
+                                                                                      \
   if (UseCompressedOops) {                                                            \
     InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr);    \
   } else {                                                                            \
@@ -257,8 +318,12 @@
 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
 
 #ifndef SERIALGC
-void instanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
-  instanceKlass::oop_push_contents(pm, obj);
+void InstanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
+  // Note that we don't have to follow the mirror -> klass pointer, since all
+  // klasses that are dirty will be scavenged when we iterate over the
+  // ClassLoaderData objects.
+
+  InstanceKlass::oop_push_contents(pm, obj);
   InstanceMirrorKlass_OOP_ITERATE(                                            \
     start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
     if (PSScavenge::should_scavenge(p)) {                                     \
@@ -267,39 +332,52 @@
     assert_nothing )
 }
 
-int instanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
-  instanceKlass::oop_update_pointers(cm, obj);
+int InstanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
+  int size = oop_size(obj);
+  InstanceKlass::oop_update_pointers(cm, obj);
+
+  // Follow the klass field in the mirror.
+  Klass* klass = java_lang_Class::as_Klass(obj);
+  if (klass != NULL) {
+    PSParallelCompact::adjust_klass(cm, klass);
+  } else {
+    // If klass is NULL then this a mirror for a primitive type.
+    // We don't have to follow them, since they are handled as strong
+    // roots in Universe::oops_do.
+    assert(java_lang_Class::is_primitive(obj), "Sanity check");
+  }
+
   InstanceMirrorKlass_OOP_ITERATE(                                            \
     start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
     PSParallelCompact::adjust_pointer(p),                                     \
     assert_nothing)
-  return oop_size(obj);
+  return size;
 }
 #endif // SERIALGC
 
-int instanceMirrorKlass::instance_size(KlassHandle k) {
+int InstanceMirrorKlass::instance_size(KlassHandle k) {
   if (k() != NULL && k->oop_is_instance()) {
-    return align_object_size(size_helper() + instanceKlass::cast(k())->static_field_size());
+    return align_object_size(size_helper() + InstanceKlass::cast(k())->static_field_size());
   }
   return size_helper();
 }
 
-instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
+instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
   // Query before forming handle.
   int size = instance_size(k);
-  KlassHandle h_k(THREAD, as_klassOop());
+  KlassHandle h_k(THREAD, this);
   instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL);
   return i;
 }
 
-int instanceMirrorKlass::oop_size(oop obj) const {
+int InstanceMirrorKlass::oop_size(oop obj) const {
   return java_lang_Class::oop_size(obj);
 }
 
-int instanceMirrorKlass::compute_static_oop_field_count(oop obj) {
-  klassOop k = java_lang_Class::as_klassOop(obj);
-  if (k != NULL && k->klass_part()->oop_is_instance()) {
-    return instanceKlass::cast(k)->static_oop_field_count();
+int InstanceMirrorKlass::compute_static_oop_field_count(oop obj) {
+  Klass* k = java_lang_Class::as_Klass(obj);
+  if (k != NULL && k->oop_is_instance()) {
+    return InstanceKlass::cast(k)->static_oop_field_count();
   }
   return 0;
 }