< prev index next >
src/share/vm/gc/serial/markSweep.cpp
Print this page
@@ -26,10 +26,12 @@
#include "compiler/compileBroker.hpp"
#include "gc/serial/markSweep.inline.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp"
+#include "gc/shared/specialized_oop_closures.hpp"
+#include "memory/iterator.inline.hpp"
#include "oops/instanceKlass.inline.hpp"
#include "oops/instanceMirrorKlass.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.inline.hpp"
#include "oops/oop.inline.hpp"
@@ -51,177 +53,37 @@
MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); }
void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
-MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure;
+MarkAndPushClosure MarkSweep::mark_and_push_closure;
CLDToOopClosure MarkSweep::follow_cld_closure(&mark_and_push_closure);
CLDToOopClosure MarkSweep::adjust_cld_closure(&adjust_pointer_closure);
template <typename T>
-void MarkSweep::MarkAndPushClosure::do_oop_nv(T* p) { mark_and_push(p); }
-void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { do_oop_nv(p); }
-void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
-
-void MarkSweep::follow_class_loader(ClassLoaderData* cld) {
- MarkSweep::follow_cld_closure.do_cld(cld);
-}
-
-void InstanceKlass::oop_ms_follow_contents(oop obj) {
- assert(obj != NULL, "can't follow the content of NULL object");
- MarkSweep::follow_klass(this);
-
- oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::mark_and_push_closure);
-}
-
-void InstanceMirrorKlass::oop_ms_follow_contents(oop obj) {
- InstanceKlass::oop_ms_follow_contents(obj);
-
- // Follow the klass field in the mirror
- Klass* klass = java_lang_Class::as_Klass(obj);
- if (klass != NULL) {
- // An anonymous class doesn't have its own class loader, so the call
- // to follow_klass will mark and push its java mirror instead of the
- // class loader. When handling the java mirror for an anonymous class
- // we need to make sure its class loader data is claimed, this is done
- // by calling follow_class_loader explicitly. For non-anonymous classes
- // the call to follow_class_loader is made when the class loader itself
- // is handled.
- if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
- MarkSweep::follow_class_loader(klass->class_loader_data());
- } else {
- 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");
- }
-
- oop_oop_iterate_statics<true>(obj, &MarkSweep::mark_and_push_closure);
-}
-
-void InstanceClassLoaderKlass::oop_ms_follow_contents(oop obj) {
- InstanceKlass::oop_ms_follow_contents(obj);
-
- ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
+void MarkAndPushClosure::do_oop_nv(T* p) { MarkSweep::mark_and_push(p); }
+void MarkAndPushClosure::do_oop(oop* p) { do_oop_nv(p); }
+void MarkAndPushClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
+bool MarkAndPushClosure::do_metadata() { return do_metadata_nv(); }
+bool MarkAndPushClosure::do_metadata_nv() { return true; }
+void MarkAndPushClosure::do_klass(Klass* k) { do_klass_nv(k); }
+void MarkAndPushClosure::do_klass_nv(Klass* k) { MarkSweep::follow_klass(k); }
+void MarkAndPushClosure::do_cld(ClassLoaderData* cld) { do_cld_nv(cld); }
+void MarkAndPushClosure::do_cld_nv(ClassLoaderData* cld) { MarkSweep::follow_cld(cld); }
- // We must NULL check here, since the class loader
- // can be found before the loader data has been set up.
- if(loader_data != NULL) {
- MarkSweep::follow_class_loader(loader_data);
- }
-}
-
-template <class T>
-static void oop_ms_follow_contents_specialized(InstanceRefKlass* klass, oop obj) {
- T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
- T heap_oop = oopDesc::load_heap_oop(referent_addr);
- debug_only(
- if(TraceReferenceGC && PrintGCDetails) {
- gclog_or_tty->print_cr("InstanceRefKlass::oop_ms_follow_contents_specialized " PTR_FORMAT, p2i(obj));
- }
- )
- if (!oopDesc::is_null(heap_oop)) {
- oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
- if (!referent->is_gc_marked() &&
- MarkSweep::ref_processor()->discover_reference(obj, klass->reference_type())) {
- // reference was discovered, referent will be traversed later
- klass->InstanceKlass::oop_ms_follow_contents(obj);
- debug_only(
- if(TraceReferenceGC && PrintGCDetails) {
- gclog_or_tty->print_cr(" Non NULL enqueued " PTR_FORMAT, p2i(obj));
- }
- )
- return;
- } else {
- // treat referent as normal oop
- debug_only(
- if(TraceReferenceGC && PrintGCDetails) {
- gclog_or_tty->print_cr(" Non NULL normal " PTR_FORMAT, p2i(obj));
- }
- )
- MarkSweep::mark_and_push(referent_addr);
- }
- }
- T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
- // Treat discovered as normal oop, if ref is not "active",
- // i.e. if next is non-NULL.
- T next_oop = oopDesc::load_heap_oop(next_addr);
- if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
- T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
- debug_only(
- if(TraceReferenceGC && PrintGCDetails) {
- gclog_or_tty->print_cr(" Process discovered as normal "
- PTR_FORMAT, p2i(discovered_addr));
- }
- )
- MarkSweep::mark_and_push(discovered_addr);
- }
- // treat next as normal oop. next is a link in the reference queue.
- debug_only(
- if(TraceReferenceGC && PrintGCDetails) {
- gclog_or_tty->print_cr(" Process next as normal " PTR_FORMAT, p2i(next_addr));
- }
- )
- MarkSweep::mark_and_push(next_addr);
- klass->InstanceKlass::oop_ms_follow_contents(obj);
-}
-
-void InstanceRefKlass::oop_ms_follow_contents(oop obj) {
- if (UseCompressedOops) {
- oop_ms_follow_contents_specialized<narrowOop>(this, obj);
- } else {
- oop_ms_follow_contents_specialized<oop>(this, obj);
- }
-}
-
-template <class T>
-static void oop_ms_follow_contents_specialized(oop obj, int index) {
- objArrayOop a = objArrayOop(obj);
- const size_t len = size_t(a->length());
- const size_t beg_index = size_t(index);
+void MarkSweep::follow_array(objArrayOop array, int index) {
+ const int len = array->length();
+ const int beg_index = index;
assert(beg_index < len || len == 0, "index too large");
- const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
- const size_t end_index = beg_index + stride;
- T* const base = (T*)a->base();
- T* const beg = base + beg_index;
- T* const end = base + end_index;
-
- // Push the non-NULL elements of the next stride on the marking stack.
- for (T* e = beg; e < end; e++) {
- MarkSweep::mark_and_push<T>(e);
- }
-
- if (end_index < len) {
- MarkSweep::push_objarray(a, end_index); // Push the continuation.
- }
-}
-
-void ObjArrayKlass::oop_ms_follow_contents(oop obj) {
- assert (obj->is_array(), "obj must be array");
- MarkSweep::follow_klass(this);
- if (UseCompressedOops) {
- oop_ms_follow_contents_specialized<narrowOop>(obj, 0);
- } else {
- oop_ms_follow_contents_specialized<oop>(obj, 0);
- }
-}
+ const int stride = MIN2(len - beg_index, (int) ObjArrayMarkingStride);
+ const int end_index = beg_index + stride;
-void TypeArrayKlass::oop_ms_follow_contents(oop obj) {
- assert(obj->is_typeArray(),"must be a type array");
- // Performance tweak: We skip iterating over the klass pointer since we
- // know that Universe::TypeArrayKlass never moves.
-}
+ array->oop_iterate_range(&mark_and_push_closure, beg_index, end_index);
-void MarkSweep::follow_array(objArrayOop array, int index) {
- if (UseCompressedOops) {
- oop_ms_follow_contents_specialized<narrowOop>(array, index);
- } else {
- oop_ms_follow_contents_specialized<oop>(array, index);
+ if (end_index < len) {
+ MarkSweep::push_objarray(array, end_index); // Push the continuation.
}
}
void MarkSweep::follow_stack() {
do {
@@ -264,10 +126,15 @@
_preserved_mark_stack.push(mark);
_preserved_oop_stack.push(obj);
}
}
+void MarkSweep::set_ref_processor(ReferenceProcessor* rp) {
+ _ref_processor = rp;
+ mark_and_push_closure.set_ref_processor(_ref_processor);
+}
+
MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure;
template <typename T>
void MarkSweep::AdjustPointerClosure::do_oop_nv(T* p) { adjust_pointer(p); }
void MarkSweep::AdjustPointerClosure::do_oop(oop* p) { do_oop_nv(p); }
@@ -403,5 +270,8 @@
typeArrayOop t = typeArrayOop(obj);
// Performance tweak: We skip iterating over the klass pointer since we
// know that Universe::TypeArrayKlass never moves.
return t->object_size();
}
+
+// Generate MS specialized oop_oop_iterate functions.
+SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_MS(ALL_KLASS_OOP_OOP_ITERATE_DEFN)
< prev index next >