8191567: Refactor ciInstanceKlass G1 keep alive barrier to use Access API

Reviewed-by: dholmes, rkennke, tschatzl
This commit is contained in:
Erik Österlund 2018-01-08 13:22:05 +01:00
parent 01ab4faae4
commit 8f739404a7
4 changed files with 21 additions and 25 deletions

View File

@ -34,35 +34,12 @@
#include "oops/oop.inline.hpp"
#include "oops/fieldStreams.hpp"
#include "runtime/fieldDescriptor.hpp"
#if INCLUDE_ALL_GCS
# include "gc/g1/g1SATBCardTableModRefBS.hpp"
#endif
// ciInstanceKlass
//
// This class represents a Klass* in the HotSpot virtual machine
// whose Klass part in an InstanceKlass.
// ------------------------------------------------------------------
// ensure_metadata_alive
//
// Ensure that the metadata wrapped by the ciMetadata is kept alive by GC.
// This is primarily useful for metadata which is considered as weak roots
// by the GC but need to be strong roots if reachable from a current compilation.
// InstanceKlass are created for both weak and strong metadata. Ensuring this metadata
// alive covers the cases where there are weak roots without performance cost.
//
static void ensure_metadata_alive(oop metadata_holder) {
#if INCLUDE_ALL_GCS
if (!UseG1GC) {
return;
}
if (metadata_holder != NULL) {
G1SATBCardTableModRefBS::enqueue(metadata_holder);
}
#endif
}
// ------------------------------------------------------------------
// ciInstanceKlass::ciInstanceKlass
@ -88,8 +65,12 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) :
_has_injected_fields = -1;
_implementor = NULL; // we will fill these lazily
oop holder = ik->klass_holder();
ensure_metadata_alive(holder);
// Ensure that the metadata wrapped by the ciMetadata is kept alive by GC.
// This is primarily useful for metadata which is considered as weak roots
// by the GC but need to be strong roots if reachable from a current compilation.
// InstanceKlass are created for both weak and strong metadata. Ensuring this metadata
// alive covers the cases where there are weak roots without performance cost.
oop holder = ik->klass_holder_phantom();
if (ik->is_anonymous()) {
// Though ciInstanceKlass records class loader oop, it's not enough to keep
// VM anonymous classes alive (loader == NULL). Klass holder should be used instead.

View File

@ -217,6 +217,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
friend class ClassLoaderDataGraphKlassIteratorAtomic;
friend class ClassLoaderDataGraphKlassIteratorStatic;
friend class ClassLoaderDataGraphMetaspaceIterator;
friend class InstanceKlass;
friend class MetaDataFactory;
friend class Method;

View File

@ -3421,6 +3421,15 @@ void JNIid::verify(Klass* holder) {
}
}
oop InstanceKlass::klass_holder_phantom() {
oop* addr;
if (is_anonymous()) {
addr = _java_mirror.ptr_raw();
} else {
addr = &class_loader_data()->_class_loader;
}
return RootAccess<IN_CONCURRENT_ROOT | ON_PHANTOM_OOP_REF>::oop_load(addr);
}
#ifdef ASSERT
void InstanceKlass::set_init_state(ClassState state) {

View File

@ -640,6 +640,11 @@ class InstanceKlass: public Klass {
return is_anonymous() ? java_mirror() : class_loader();
}
// Load the klass_holder as a phantom. This is useful when a weak Klass
// pointer has been "peeked" and then must be kept alive before it may
// be used safely.
oop klass_holder_phantom();
bool is_contended() const {
return (_misc_flags & _misc_is_contended) != 0;
}