8138737: Remove oop_ms_adjust_pointers and use oop_iterate instead

Reviewed-by: kbarrett, stefank
This commit is contained in:
Stefan Johansson 2017-04-26 10:26:39 +02:00
parent 111afb73a5
commit e237e703df
15 changed files with 162 additions and 150 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -224,12 +224,12 @@ void MarkSweep::set_ref_processor(ReferenceProcessor* rp) {
mark_and_push_closure.set_ref_processor(_ref_processor);
}
MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure;
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); }
void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
void AdjustPointerClosure::do_oop_nv(T* p) { MarkSweep::adjust_pointer(p); }
void AdjustPointerClosure::do_oop(oop* p) { do_oop_nv(p); }
void AdjustPointerClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
void MarkSweep::adjust_marks() {
assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(),
@ -280,79 +280,5 @@ void marksweep_init() {
MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
}
int InstanceKlass::oop_ms_adjust_pointers(oop obj) {
int size = size_helper();
oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::adjust_pointer_closure);
return size;
}
int InstanceMirrorKlass::oop_ms_adjust_pointers(oop obj) {
int size = oop_size(obj);
InstanceKlass::oop_ms_adjust_pointers(obj);
oop_oop_iterate_statics<true>(obj, &MarkSweep::adjust_pointer_closure);
return size;
}
int InstanceClassLoaderKlass::oop_ms_adjust_pointers(oop obj) {
return InstanceKlass::oop_ms_adjust_pointers(obj);
}
#ifdef ASSERT
template <class T> static void trace_reference_gc(const char *s, oop obj,
T* referent_addr,
T* next_addr,
T* discovered_addr) {
log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(referent_addr), p2i(referent_addr ? (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
log_develop_trace(gc, ref)(" next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(next_addr), p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
log_develop_trace(gc, ref)(" discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(discovered_addr), p2i(discovered_addr ? (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
}
#endif
template <class T> void static adjust_object_specialized(oop obj) {
T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
MarkSweep::adjust_pointer(referent_addr);
T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
MarkSweep::adjust_pointer(next_addr);
T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
MarkSweep::adjust_pointer(discovered_addr);
debug_only(trace_reference_gc("InstanceRefKlass::oop_ms_adjust_pointers", obj,
referent_addr, next_addr, discovered_addr);)
}
int InstanceRefKlass::oop_ms_adjust_pointers(oop obj) {
int size = size_helper();
InstanceKlass::oop_ms_adjust_pointers(obj);
if (UseCompressedOops) {
adjust_object_specialized<narrowOop>(obj);
} else {
adjust_object_specialized<oop>(obj);
}
return size;
}
int ObjArrayKlass::oop_ms_adjust_pointers(oop obj) {
assert(obj->is_objArray(), "obj must be obj array");
objArrayOop a = objArrayOop(obj);
// Get size before changing pointers.
// Don't call size() or oop_size() since that is a virtual call.
int size = a->object_size();
oop_oop_iterate_elements<true>(a, &MarkSweep::adjust_pointer_closure);
return size;
}
int TypeArrayKlass::oop_ms_adjust_pointers(oop obj) {
assert(obj->is_typeArray(), "must be a type array");
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)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -50,6 +50,7 @@ class STWGCTimer;
// declared at end
class PreservedMark;
class MarkAndPushClosure;
class AdjustPointerClosure;
class MarkSweep : AllStatic {
//
@ -66,16 +67,6 @@ class MarkSweep : AllStatic {
virtual void do_void();
};
class AdjustPointerClosure: public OopsInGenClosure {
public:
template <typename T> void do_oop_nv(T* p);
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
// This closure provides its own oop verification code.
debug_only(virtual bool should_verify_oops() { return false; })
};
// Used for java/lang/ref handling
class IsAliveClosure: public BoolObjectClosure {
public:
@ -201,6 +192,17 @@ public:
}
};
class AdjustPointerClosure: public OopsInGenClosure {
public:
template <typename T> void do_oop_nv(T* p);
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
// This closure provides its own oop verification code.
debug_only(virtual bool should_verify_oops() { return false; })
};
class PreservedMark VALUE_OBJ_CLASS_SPEC {
private:
oop _obj;

View File

@ -42,7 +42,7 @@ inline bool MarkSweep::is_archive_object(oop object) {
}
inline int MarkSweep::adjust_pointers(oop obj) {
return obj->ms_adjust_pointers();
return obj->oop_iterate_size(&MarkSweep::adjust_pointer_closure);
}
template <class T> inline void MarkSweep::adjust_pointer(T* p) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -44,6 +44,7 @@ class FastScanClosure;
class FilteringClosure;
// MarkSweep
class MarkAndPushClosure;
class AdjustPointerClosure;
// ParNew
class ParScanWithBarrierClosure;
class ParScanWithoutBarrierClosure;
@ -90,7 +91,8 @@ class NoHeaderExtendedOopClosure;
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f)
#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_MS(f) \
f(MarkAndPushClosure,_nv)
f(MarkAndPushClosure,_nv) \
f(AdjustPointerClosure,_nv)
#if INCLUDE_ALL_GCS
#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_CMS(f) \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -65,6 +65,16 @@ class ExtendedOopClosure : public OopClosure {
public:
ReferenceProcessor* ref_processor() const { return _ref_processor; }
// Iteration of InstanceRefKlasses differ depending on the closure,
// the below enum describes the different alternatives.
enum ReferenceIterationMode {
DO_DISCOVERY, // Apply closure and discover references
DO_FIELDS // Apply closure to all fields
};
// The default iteration mode is to do discovery.
virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERY; }
// If the do_metadata functions return "true",
// we invoke the following when running oop_iterate():
//

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, 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
@ -48,8 +48,6 @@ public:
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);

View File

@ -1163,8 +1163,6 @@ public:
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);

View File

@ -89,8 +89,6 @@ class InstanceMirrorKlass: public InstanceKlass {
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -58,8 +58,6 @@ class InstanceRefKlass: public InstanceKlass {
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);
@ -107,6 +105,30 @@ private:
template <bool nv, class OopClosureType>
inline void oop_oop_iterate_ref_processing(oop obj, OopClosureType* closure);
// Building blocks for specialized handling.
template <bool nv, typename T, class OopClosureType, class Contains>
static void do_referent(oop obj, OopClosureType* closure, Contains& contains);
template <bool nv, typename T, class OopClosureType, class Contains>
static void do_next(oop obj, OopClosureType* closure, Contains& contains);
template <bool nv, typename T, class OopClosureType, class Contains>
static void do_discovered(oop obj, OopClosureType* closure, Contains& contains);
template <typename T, class OopClosureType>
static bool try_discover(oop obj, ReferenceType type, OopClosureType* closure);
// Do discovery while handling InstanceRefKlasses. Reference discovery
// is only done if the closure provides a ReferenceProcessor.
template <bool nv, typename T, class OopClosureType, class Contains>
static void oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains);
// Apply the closure to all fields. No reference discovery is done.
template <bool nv, typename T, class OopClosureType, class Contains>
static void oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains);
template <typename T>
static void trace_reference_gc(const char *s, oop obj, T* referent_addr, T* next_addr, T* discovered_addr) NOT_DEBUG_RETURN;
public:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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
@ -36,39 +36,99 @@
#include "utilities/macros.hpp"
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) {
T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
if (closure->apply_to_weak_ref_discovered_field()) {
Devirtualizer<nv>::do_oop(closure, disc_addr);
}
void InstanceRefKlass::do_referent(oop obj, OopClosureType* closure, Contains& contains) {
T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
T heap_oop = oopDesc::load_heap_oop(referent_addr);
ReferenceProcessor* rp = closure->ref_processor();
if (!oopDesc::is_null(heap_oop)) {
oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
if (!referent->is_gc_marked() && (rp != NULL) &&
rp->discover_reference(obj, reference_type())) {
return;
} else if (contains(referent_addr)) {
// treat referent as normal oop
if (contains(referent_addr)) {
Devirtualizer<nv>::do_oop(closure, referent_addr);
}
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::do_next(oop obj, OopClosureType* closure, Contains& contains) {
T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
T next_oop = oopDesc::load_heap_oop(next_addr);
// Treat discovered as normal oop, if ref is not "active" (next non-NULL)
if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {
// i.e. ref is not "active"
log_develop_trace(gc, ref)(" Process discovered as normal " PTR_FORMAT, p2i(disc_addr));
Devirtualizer<nv>::do_oop(closure, disc_addr);
}
// treat next as normal oop
if (contains(next_addr)) {
Devirtualizer<nv>::do_oop(closure, next_addr);
}
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) {
T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
if (contains(discovered_addr)) {
Devirtualizer<nv>::do_oop(closure, discovered_addr);
}
}
template <typename T, class OopClosureType>
bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {
ReferenceProcessor* rp = closure->ref_processor();
if (rp != NULL) {
T referent_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::referent_addr(obj));
if (!oopDesc::is_null(referent_oop)) {
oop referent = oopDesc::decode_heap_oop_not_null(referent_oop);
if (!referent->is_gc_marked()) {
// Only try to discover if not yet marked.
return rp->discover_reference(obj, type);
}
}
}
return false;
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) {
log_develop_trace(gc, ref)("Process reference with discovery " PTR_FORMAT, p2i(obj));
// Special case for some closures.
if (closure->apply_to_weak_ref_discovered_field()) {
do_discovered<nv, T>(obj, closure, contains);
}
// Try to discover reference and return if it succeeds.
if (try_discover<T>(obj, type, closure)) {
return;
}
// Treat referent as normal oop.
do_referent<nv, T>(obj, closure, contains);
// Treat discovered as normal oop, if ref is not "active" (next non-NULL).
T next_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::next_addr(obj));
if (!oopDesc::is_null(next_oop)) {
do_discovered<nv, T>(obj, closure, contains);
}
// Treat next as normal oop.
do_next<nv, T>(obj, closure, contains);
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains) {
do_referent<nv, T>(obj, closure, contains);
do_discovered<nv, T>(obj, closure, contains);
do_next<nv, T>(obj, closure, contains);
trace_reference_gc("InstanceRefKlass::oop_oop_iterate_fields()",
obj,
(T*)java_lang_ref_Reference::referent_addr(obj),
(T*)java_lang_ref_Reference::next_addr(obj),
(T*)java_lang_ref_Reference::discovered_addr(obj));
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) {
switch (closure->reference_iteration_mode()) {
case ExtendedOopClosure::DO_DISCOVERY:
oop_oop_iterate_discovery<nv, T>(obj, reference_type(), closure, contains);
break;
case ExtendedOopClosure::DO_FIELDS:
oop_oop_iterate_fields<nv, T>(obj, closure, contains);
break;
default:
ShouldNotReachHere();
}
}
class AlwaysContains {
public:
template <typename T> bool operator()(T* p) const { return true; }
@ -125,6 +185,19 @@ void InstanceRefKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure,
oop_oop_iterate_ref_processing_bounded<nv>(obj, closure, mr);
}
#ifdef ASSERT
template <typename T>
void InstanceRefKlass::trace_reference_gc(const char *s, oop obj, T* referent_addr, T* next_addr, T* discovered_addr) {
log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(referent_addr), p2i(referent_addr ? (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
log_develop_trace(gc, ref)(" next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(next_addr), p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
log_develop_trace(gc, ref)(" discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(discovered_addr), p2i(discovered_addr ? (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
}
#endif
// Macro to define InstanceRefKlass::oop_oop_iterate for virtual/nonvirtual for
// all closures. Macros calling macros above for each oop size.
#define ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \

View File

@ -609,8 +609,6 @@ protected:
// GC specific object visitors
//
// Mark Sweep
virtual int oop_ms_adjust_pointers(oop obj) = 0;
#if INCLUDE_ALL_GCS
// Parallel Scavenge
virtual void oop_ps_push_contents( oop obj, PSPromotionManager* pm) = 0;

View File

@ -112,8 +112,6 @@ class ObjArrayKlass : public ArrayKlass {
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -325,10 +325,6 @@ class oopDesc {
// Garbage Collection support
// Mark Sweep
// Adjust all pointers in this object to point at it's forwarded location and
// return the size of this oop. This is used by the MarkSweep collector.
inline int ms_adjust_pointers();
#if INCLUDE_ALL_GCS
// Parallel Compact
inline void pc_follow_contents(ParCompactionManager* cm);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -664,13 +664,6 @@ void oopDesc::incr_age() {
}
}
int oopDesc::ms_adjust_pointers() {
debug_only(int check_size = size());
int s = klass()->oop_ms_adjust_pointers(this);
assert(s == check_size, "should be the same");
return s;
}
#if INCLUDE_ALL_GCS
void oopDesc::pc_follow_contents(ParCompactionManager* cm) {
klass()->oop_pc_follow_contents(this, cm);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -74,8 +74,6 @@ class TypeArrayKlass : public ArrayKlass {
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);