mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-15 08:34:30 +02:00
8247879: Rework WeakHandle and OopHandle to dynamically support different OopStorages
Reviewed-by: coleenp, eosterlund
This commit is contained in:
parent
b7e944953e
commit
17f2250c5a
17 changed files with 84 additions and 112 deletions
|
@ -55,6 +55,7 @@
|
|||
#include "classfile/packageEntry.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
|
@ -487,7 +488,7 @@ void ClassLoaderData::add_class(Klass* k, bool publicize /* true */) {
|
|||
void ClassLoaderData::initialize_holder(Handle loader_or_mirror) {
|
||||
if (loader_or_mirror() != NULL) {
|
||||
assert(_holder.is_null(), "never replace holders");
|
||||
_holder = WeakHandle<vm_weak_data>::create(loader_or_mirror);
|
||||
_holder = WeakHandle(OopStorageSet::vm_weak(), loader_or_mirror);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -654,7 +655,7 @@ ClassLoaderData::~ClassLoaderData() {
|
|||
ClassLoaderDataGraph::dec_instance_classes(cl.instance_class_released());
|
||||
|
||||
// Release the WeakHandle
|
||||
_holder.release();
|
||||
_holder.release(OopStorageSet::vm_weak());
|
||||
|
||||
// Release C heap allocated hashtable for all the packages.
|
||||
if (_packages != NULL) {
|
||||
|
|
|
@ -109,9 +109,9 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||
|
||||
static ClassLoaderData * _the_null_class_loader_data;
|
||||
|
||||
WeakHandle<vm_weak_data> _holder; // The oop that determines lifetime of this class loader
|
||||
OopHandle _class_loader; // The instance of java/lang/ClassLoader associated with
|
||||
// this ClassLoaderData
|
||||
WeakHandle _holder; // The oop that determines lifetime of this class loader
|
||||
OopHandle _class_loader; // The instance of java/lang/ClassLoader associated with
|
||||
// this ClassLoaderData
|
||||
|
||||
ClassLoaderMetaspace * volatile _metaspace; // Meta-space where meta-data defined by the
|
||||
// classes in the class loader are allocated.
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "classfile/dictionary.hpp"
|
||||
#include "classfile/protectionDomainCache.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
|
@ -406,14 +407,14 @@ oop SymbolPropertyEntry::method_type() const {
|
|||
}
|
||||
|
||||
void SymbolPropertyEntry::set_method_type(oop p) {
|
||||
_method_type = OopHandle::create(p);
|
||||
_method_type = OopHandle(OopStorageSet::vm_global(), p);
|
||||
}
|
||||
|
||||
void SymbolPropertyEntry::free_entry() {
|
||||
// decrement Symbol refcount here because hashtable doesn't.
|
||||
literal()->decrement_refcount();
|
||||
// Free OopHandle
|
||||
_method_type.release();
|
||||
_method_type.release(OopStorageSet::vm_global());
|
||||
}
|
||||
|
||||
SymbolPropertyTable::SymbolPropertyTable(int table_size)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "classfile/dictionary.hpp"
|
||||
#include "classfile/protectionDomainCache.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
|
@ -45,7 +46,7 @@ int ProtectionDomainCacheTable::index_for(Handle protection_domain) {
|
|||
}
|
||||
|
||||
ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size)
|
||||
: Hashtable<WeakHandle<vm_weak_data>, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry))
|
||||
: Hashtable<WeakHandle, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry))
|
||||
{ _dead_entries = false;
|
||||
_total_oops_removed = 0;
|
||||
}
|
||||
|
@ -93,7 +94,7 @@ void ProtectionDomainCacheTable::unlink() {
|
|||
LogStream ls(lt);
|
||||
ls.print_cr("protection domain unlinked at %d", i);
|
||||
}
|
||||
entry->literal().release();
|
||||
entry->literal().release(OopStorageSet::vm_weak());
|
||||
*p = entry->next();
|
||||
free_entry(entry);
|
||||
}
|
||||
|
@ -180,8 +181,8 @@ ProtectionDomainCacheEntry* ProtectionDomainCacheTable::add_entry(int index, uns
|
|||
protection_domain->print_value_on(&ls);
|
||||
ls.cr();
|
||||
}
|
||||
WeakHandle<vm_weak_data> w = WeakHandle<vm_weak_data>::create(protection_domain);
|
||||
WeakHandle w(OopStorageSet::vm_weak(), protection_domain);
|
||||
ProtectionDomainCacheEntry* p = new_entry(hash, w);
|
||||
Hashtable<WeakHandle<vm_weak_data>, mtClass>::add_entry(index, p);
|
||||
Hashtable<WeakHandle, mtClass>::add_entry(index, p);
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -35,18 +35,18 @@
|
|||
// to dictionary.hpp pd_set for more information about how protection domain entries
|
||||
// are used.
|
||||
// This table is walked during GC, rather than the class loader data graph dictionaries.
|
||||
class ProtectionDomainCacheEntry : public HashtableEntry<WeakHandle<vm_weak_data>, mtClass> {
|
||||
class ProtectionDomainCacheEntry : public HashtableEntry<WeakHandle, mtClass> {
|
||||
friend class VMStructs;
|
||||
public:
|
||||
oop object();
|
||||
oop object_no_keepalive();
|
||||
|
||||
ProtectionDomainCacheEntry* next() {
|
||||
return (ProtectionDomainCacheEntry*)HashtableEntry<WeakHandle<vm_weak_data>, mtClass>::next();
|
||||
return (ProtectionDomainCacheEntry*)HashtableEntry<WeakHandle, mtClass>::next();
|
||||
}
|
||||
|
||||
ProtectionDomainCacheEntry** next_addr() {
|
||||
return (ProtectionDomainCacheEntry**)HashtableEntry<WeakHandle<vm_weak_data>, mtClass>::next_addr();
|
||||
return (ProtectionDomainCacheEntry**)HashtableEntry<WeakHandle, mtClass>::next_addr();
|
||||
}
|
||||
|
||||
void verify();
|
||||
|
@ -61,21 +61,21 @@ class ProtectionDomainCacheEntry : public HashtableEntry<WeakHandle<vm_weak_data
|
|||
// we only need to iterate over this set.
|
||||
// The amount of different protection domains used is typically magnitudes smaller
|
||||
// than the number of system dictionary entries (loaded classes).
|
||||
class ProtectionDomainCacheTable : public Hashtable<WeakHandle<vm_weak_data>, mtClass> {
|
||||
class ProtectionDomainCacheTable : public Hashtable<WeakHandle, mtClass> {
|
||||
friend class VMStructs;
|
||||
private:
|
||||
ProtectionDomainCacheEntry* bucket(int i) const {
|
||||
return (ProtectionDomainCacheEntry*) Hashtable<WeakHandle<vm_weak_data>, mtClass>::bucket(i);
|
||||
return (ProtectionDomainCacheEntry*) Hashtable<WeakHandle, mtClass>::bucket(i);
|
||||
}
|
||||
|
||||
// The following method is not MT-safe and must be done under lock.
|
||||
ProtectionDomainCacheEntry** bucket_addr(int i) {
|
||||
return (ProtectionDomainCacheEntry**) Hashtable<WeakHandle<vm_weak_data>, mtClass>::bucket_addr(i);
|
||||
return (ProtectionDomainCacheEntry**) Hashtable<WeakHandle, mtClass>::bucket_addr(i);
|
||||
}
|
||||
|
||||
ProtectionDomainCacheEntry* new_entry(unsigned int hash, WeakHandle<vm_weak_data> protection_domain) {
|
||||
ProtectionDomainCacheEntry* new_entry(unsigned int hash, WeakHandle protection_domain) {
|
||||
ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*)
|
||||
Hashtable<WeakHandle<vm_weak_data>, mtClass>::new_entry(hash, protection_domain);
|
||||
Hashtable<WeakHandle, mtClass>::new_entry(hash, protection_domain);
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ uintx hash_string(const jchar* s, int len, bool useAlt) {
|
|||
class StringTableConfig : public StackObj {
|
||||
private:
|
||||
public:
|
||||
typedef WeakHandle<vm_string_table_data> Value;
|
||||
typedef WeakHandle Value;
|
||||
|
||||
static uintx get_hash(Value const& value, bool* is_dead) {
|
||||
EXCEPTION_MARK;
|
||||
|
@ -129,7 +129,7 @@ class StringTableConfig : public StackObj {
|
|||
return AllocateHeap(size, mtSymbol);
|
||||
}
|
||||
static void free_node(void* memory, Value const& value) {
|
||||
value.release();
|
||||
value.release(OopStorageSet::string_table_weak());
|
||||
FreeHeap(memory);
|
||||
StringTable::item_removed();
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ class StringTableLookupJchar : StackObj {
|
|||
uintx get_hash() const {
|
||||
return _hash;
|
||||
}
|
||||
bool equals(WeakHandle<vm_string_table_data>* value, bool* is_dead) {
|
||||
bool equals(WeakHandle* value, bool* is_dead) {
|
||||
oop val_oop = value->peek();
|
||||
if (val_oop == NULL) {
|
||||
// dead oop, mark this hash dead for cleaning
|
||||
|
@ -182,7 +182,7 @@ class StringTableLookupOop : public StackObj {
|
|||
return _hash;
|
||||
}
|
||||
|
||||
bool equals(WeakHandle<vm_string_table_data>* value, bool* is_dead) {
|
||||
bool equals(WeakHandle* value, bool* is_dead) {
|
||||
oop val_oop = value->peek();
|
||||
if (val_oop == NULL) {
|
||||
// dead oop, mark this hash dead for cleaning
|
||||
|
@ -272,7 +272,7 @@ class StringTableGet : public StackObj {
|
|||
Handle _return;
|
||||
public:
|
||||
StringTableGet(Thread* thread) : _thread(thread) {}
|
||||
void operator()(WeakHandle<vm_string_table_data>* val) {
|
||||
void operator()(WeakHandle* val) {
|
||||
oop result = val->resolve();
|
||||
assert(result != NULL, "Result should be reachable");
|
||||
_return = Handle(_thread, result);
|
||||
|
@ -368,7 +368,7 @@ oop StringTable::do_intern(Handle string_or_null_h, const jchar* name,
|
|||
bool rehash_warning;
|
||||
do {
|
||||
// Callers have already looked up the String using the jchar* name, so just go to add.
|
||||
WeakHandle<vm_string_table_data> wh = WeakHandle<vm_string_table_data>::create(string_h);
|
||||
WeakHandle wh(OopStorageSet::string_table_weak(), string_h);
|
||||
// The hash table takes ownership of the WeakHandle, even if it's not inserted.
|
||||
if (_local_table->insert(THREAD, lookup, wh, &rehash_warning)) {
|
||||
update_needs_rehash(rehash_warning);
|
||||
|
@ -406,7 +406,7 @@ void StringTable::grow(JavaThread* jt) {
|
|||
}
|
||||
|
||||
struct StringTableDoDelete : StackObj {
|
||||
void operator()(WeakHandle<vm_string_table_data>* val) {
|
||||
void operator()(WeakHandle* val) {
|
||||
/* do nothing */
|
||||
}
|
||||
};
|
||||
|
@ -415,7 +415,7 @@ struct StringTableDeleteCheck : StackObj {
|
|||
long _count;
|
||||
long _item;
|
||||
StringTableDeleteCheck() : _count(0), _item(0) {}
|
||||
bool operator()(WeakHandle<vm_string_table_data>* val) {
|
||||
bool operator()(WeakHandle* val) {
|
||||
++_item;
|
||||
oop tmp = val->peek();
|
||||
if (tmp == NULL) {
|
||||
|
@ -551,7 +551,7 @@ static int literal_size(oop obj) {
|
|||
}
|
||||
|
||||
struct SizeFunc : StackObj {
|
||||
size_t operator()(WeakHandle<vm_string_table_data>* val) {
|
||||
size_t operator()(WeakHandle* val) {
|
||||
oop s = val->peek();
|
||||
if (s == NULL) {
|
||||
// Dead
|
||||
|
@ -577,7 +577,7 @@ void StringTable::print_table_statistics(outputStream* st,
|
|||
// Verification
|
||||
class VerifyStrings : StackObj {
|
||||
public:
|
||||
bool operator()(WeakHandle<vm_string_table_data>* val) {
|
||||
bool operator()(WeakHandle* val) {
|
||||
oop s = val->peek();
|
||||
if (s != NULL) {
|
||||
assert(java_lang_String::length(s) >= 0, "Length on string must work.");
|
||||
|
@ -601,7 +601,7 @@ class VerifyCompStrings : StackObj {
|
|||
public:
|
||||
size_t _errors;
|
||||
VerifyCompStrings(GrowableArray<oop>* oops) : _oops(oops), _errors(0) {}
|
||||
bool operator()(WeakHandle<vm_string_table_data>* val) {
|
||||
bool operator()(WeakHandle* val) {
|
||||
oop s = val->resolve();
|
||||
if (s == NULL) {
|
||||
return true;
|
||||
|
@ -639,7 +639,7 @@ class PrintString : StackObj {
|
|||
outputStream* _st;
|
||||
public:
|
||||
PrintString(Thread* thr, outputStream* st) : _thr(thr), _st(st) {}
|
||||
bool operator()(WeakHandle<vm_string_table_data>* val) {
|
||||
bool operator()(WeakHandle* val) {
|
||||
oop s = val->peek();
|
||||
if (s == NULL) {
|
||||
return true;
|
||||
|
@ -744,7 +744,7 @@ oop StringTable::create_archived_string(oop s, Thread* THREAD) {
|
|||
struct CopyToArchive : StackObj {
|
||||
CompactHashtableWriter* _writer;
|
||||
CopyToArchive(CompactHashtableWriter* writer) : _writer(writer) {}
|
||||
bool operator()(WeakHandle<vm_string_table_data>* val) {
|
||||
bool operator()(WeakHandle* val) {
|
||||
oop s = val->peek();
|
||||
if (s == NULL) {
|
||||
return true;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "code/codeCache.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "gc/shared/gcTraceTime.inline.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "interpreter/bytecodeStream.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jfr/jfrEvents.hpp"
|
||||
|
@ -175,7 +176,7 @@ void SystemDictionary::compute_java_loaders(TRAPS) {
|
|||
vmSymbols::void_classloader_signature(),
|
||||
CHECK);
|
||||
|
||||
_java_system_loader = OopHandle::create((oop)result.get_jobject());
|
||||
_java_system_loader = OopHandle(OopStorageSet::vm_global(), (oop)result.get_jobject());
|
||||
|
||||
JavaCalls::call_static(&result,
|
||||
class_loader_klass,
|
||||
|
@ -183,7 +184,7 @@ void SystemDictionary::compute_java_loaders(TRAPS) {
|
|||
vmSymbols::void_classloader_signature(),
|
||||
CHECK);
|
||||
|
||||
_java_platform_loader = OopHandle::create((oop)result.get_jobject());
|
||||
_java_platform_loader = OopHandle(OopStorageSet::vm_global(), (oop)result.get_jobject());
|
||||
}
|
||||
|
||||
ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, bool create_mirror_cld) {
|
||||
|
@ -2041,7 +2042,7 @@ void SystemDictionary::initialize(TRAPS) {
|
|||
|
||||
// Allocate private object used as system class loader lock
|
||||
oop lock_obj = oopFactory::new_intArray(0, CHECK);
|
||||
_system_loader_lock_obj = OopHandle::create(lock_obj);
|
||||
_system_loader_lock_obj = OopHandle(OopStorageSet::vm_global(), lock_obj);
|
||||
|
||||
// Initialize basic classes
|
||||
resolve_well_known_classes(CHECK);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "classfile/systemDictionaryShared.hpp"
|
||||
#include "classfile/verificationType.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "jfr/jfrEvents.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
|
@ -1118,7 +1119,7 @@ void SystemDictionaryShared::allocate_shared_protection_domain_array(int size, T
|
|||
if (_shared_protection_domains.resolve() == NULL) {
|
||||
oop spd = oopFactory::new_objArray(
|
||||
SystemDictionary::ProtectionDomain_klass(), size, CHECK);
|
||||
_shared_protection_domains = OopHandle::create(spd);
|
||||
_shared_protection_domains = OopHandle(OopStorageSet::vm_global(), spd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1126,7 +1127,7 @@ void SystemDictionaryShared::allocate_shared_jar_url_array(int size, TRAPS) {
|
|||
if (_shared_jar_urls.resolve() == NULL) {
|
||||
oop sju = oopFactory::new_objArray(
|
||||
SystemDictionary::URL_klass(), size, CHECK);
|
||||
_shared_jar_urls = OopHandle::create(sju);
|
||||
_shared_jar_urls = OopHandle(OopStorageSet::vm_global(), sju);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1134,7 +1135,7 @@ void SystemDictionaryShared::allocate_shared_jar_manifest_array(int size, TRAPS)
|
|||
if (_shared_jar_manifests.resolve() == NULL) {
|
||||
oop sjm = oopFactory::new_objArray(
|
||||
SystemDictionary::Jar_Manifest_klass(), size, CHECK);
|
||||
_shared_jar_manifests = OopHandle::create(sjm);
|
||||
_shared_jar_manifests = OopHandle(OopStorageSet::vm_global(), sjm);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "gc/shared/oopStorageParState.inline.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
|
||||
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "compiler/oopMap.hpp"
|
||||
#include "gc/shared/barrierSet.hpp"
|
||||
#include "gc/shared/barrierSetNMethod.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "gc/shared/oopStorageParState.inline.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "gc/shared/suspendibleThreadSet.hpp"
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
#ifndef SHARE_OOPS_OOPHANDLE_HPP
|
||||
#define SHARE_OOPS_OOPHANDLE_HPP
|
||||
|
||||
#include "oops/oop.hpp"
|
||||
#include "oops/oopsHierarchy.hpp"
|
||||
|
||||
class OopStorage;
|
||||
|
||||
// Simple class for encapsulating oop pointers stored in metadata.
|
||||
// These are different from Handle. The Handle class stores pointers
|
||||
|
@ -43,13 +45,12 @@ private:
|
|||
public:
|
||||
OopHandle() : _obj(NULL) {}
|
||||
explicit OopHandle(oop* w) : _obj(w) {}
|
||||
|
||||
inline static OopHandle create(oop obj);
|
||||
OopHandle(OopStorage* storage, oop obj);
|
||||
|
||||
inline oop resolve() const;
|
||||
inline oop peek() const;
|
||||
|
||||
inline void release();
|
||||
inline void release(OopStorage* storage);
|
||||
|
||||
// Used only for removing handle.
|
||||
oop* ptr_raw() const { return _obj; }
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "oops/access.inline.hpp"
|
||||
#include "oops/oopHandle.hpp"
|
||||
#include "gc/shared/oopStorage.inline.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
|
||||
inline oop OopHandle::resolve() const {
|
||||
return (_obj == NULL) ? (oop)NULL : NativeAccess<>::oop_load(_obj);
|
||||
|
@ -38,21 +37,19 @@ inline oop OopHandle::peek() const {
|
|||
return (_obj == NULL) ? (oop)NULL : NativeAccess<AS_NO_KEEPALIVE>::oop_load(_obj);
|
||||
}
|
||||
|
||||
// Allocate a global handle and return
|
||||
inline OopHandle OopHandle::create(oop obj) {
|
||||
oop* handle = OopStorageSet::vm_global()->allocate();
|
||||
if (handle == NULL) {
|
||||
inline OopHandle::OopHandle(OopStorage* storage, oop obj) :
|
||||
_obj(storage->allocate()) {
|
||||
if (_obj == NULL) {
|
||||
vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR,
|
||||
"Cannot create oop handle");
|
||||
}
|
||||
NativeAccess<>::oop_store(handle, obj);
|
||||
return OopHandle(handle);
|
||||
NativeAccess<>::oop_store(_obj, obj);
|
||||
}
|
||||
|
||||
inline void OopHandle::release() {
|
||||
inline void OopHandle::release(OopStorage* storage) {
|
||||
// Clear the OopHandle first
|
||||
NativeAccess<>::oop_store(_obj, (oop)NULL);
|
||||
OopStorageSet::vm_global()->release(_obj);
|
||||
storage->release(_obj);
|
||||
}
|
||||
|
||||
#endif // SHARE_OOPS_OOPHANDLE_INLINE_HPP
|
||||
|
|
|
@ -31,52 +31,31 @@
|
|||
#include "utilities/debug.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
template <> OopStorage* WeakHandle<vm_weak_data>::get_storage() {
|
||||
return OopStorageSet::vm_weak();
|
||||
}
|
||||
|
||||
template <> OopStorage* WeakHandle<vm_string_table_data>::get_storage() {
|
||||
return OopStorageSet::string_table_weak();
|
||||
}
|
||||
|
||||
template <> OopStorage* WeakHandle<vm_resolved_method_table_data>::get_storage() {
|
||||
return OopStorageSet::resolved_method_table_weak();
|
||||
}
|
||||
|
||||
template <WeakHandleType T>
|
||||
WeakHandle<T> WeakHandle<T>::create(Handle obj) {
|
||||
WeakHandle::WeakHandle(OopStorage* storage, Handle obj) :
|
||||
_obj(storage->allocate()) {
|
||||
assert(obj() != NULL, "no need to create weak null oop");
|
||||
oop* oop_addr = get_storage()->allocate();
|
||||
if (oop_addr == NULL) {
|
||||
|
||||
if (_obj == NULL) {
|
||||
vm_exit_out_of_memory(sizeof(oop*), OOM_MALLOC_ERROR,
|
||||
"Unable to create new weak oop handle in OopStorage %s",
|
||||
get_storage()->name());
|
||||
storage->name());
|
||||
}
|
||||
// Create WeakHandle with address returned and store oop into it.
|
||||
NativeAccess<ON_PHANTOM_OOP_REF>::oop_store(oop_addr, obj());
|
||||
return WeakHandle(oop_addr);
|
||||
|
||||
NativeAccess<ON_PHANTOM_OOP_REF>::oop_store(_obj, obj());
|
||||
}
|
||||
|
||||
template <WeakHandleType T>
|
||||
void WeakHandle<T>::release() const {
|
||||
void WeakHandle::release(OopStorage* storage) const {
|
||||
// Only release if the pointer to the object has been created.
|
||||
if (_obj != NULL) {
|
||||
// Clear the WeakHandle. For race in creating ClassLoaderData, we can release this
|
||||
// WeakHandle before it is cleared by GC.
|
||||
NativeAccess<ON_PHANTOM_OOP_REF>::oop_store(_obj, (oop)NULL);
|
||||
get_storage()->release(_obj);
|
||||
storage->release(_obj);
|
||||
}
|
||||
}
|
||||
|
||||
template <WeakHandleType T>
|
||||
void WeakHandle<T>::print() const { print_on(tty); }
|
||||
void WeakHandle::print() const { print_on(tty); }
|
||||
|
||||
template <WeakHandleType T>
|
||||
void WeakHandle<T>::print_on(outputStream* st) const {
|
||||
void WeakHandle::print_on(outputStream* st) const {
|
||||
st->print("WeakHandle: " PTR_FORMAT, p2i(peek()));
|
||||
}
|
||||
|
||||
// Provide instantiation.
|
||||
template class WeakHandle<vm_weak_data>;
|
||||
template class WeakHandle<vm_string_table_data>;
|
||||
template class WeakHandle<vm_resolved_method_table_data>;
|
||||
|
|
|
@ -39,27 +39,19 @@ class OopStorage;
|
|||
// This is the vm version of jweak but has different GC lifetimes and policies,
|
||||
// depending on the type.
|
||||
|
||||
enum WeakHandleType {
|
||||
vm_weak_data,
|
||||
vm_string_table_data,
|
||||
vm_resolved_method_table_data
|
||||
};
|
||||
|
||||
template <WeakHandleType T>
|
||||
class WeakHandle {
|
||||
public:
|
||||
private:
|
||||
oop* _obj;
|
||||
|
||||
WeakHandle(oop* w) : _obj(w) {}
|
||||
static OopStorage* get_storage();
|
||||
public:
|
||||
WeakHandle() : _obj(NULL) {} // needed for init
|
||||
WeakHandle(OopStorage* storage, Handle obj);
|
||||
|
||||
static WeakHandle create(Handle obj);
|
||||
inline oop resolve() const;
|
||||
inline oop peek() const;
|
||||
void release() const;
|
||||
void release(OopStorage* storage) const;
|
||||
bool is_null() const { return _obj == NULL; }
|
||||
|
||||
void replace(oop with_obj);
|
||||
|
|
|
@ -28,20 +28,17 @@
|
|||
#include "oops/weakHandle.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
|
||||
template <WeakHandleType T>
|
||||
oop WeakHandle<T>::resolve() const {
|
||||
inline oop WeakHandle::resolve() const {
|
||||
assert(!is_null(), "Must be created");
|
||||
return NativeAccess<ON_PHANTOM_OOP_REF>::oop_load(_obj);
|
||||
}
|
||||
|
||||
template <WeakHandleType T>
|
||||
oop WeakHandle<T>::peek() const {
|
||||
inline oop WeakHandle::peek() const {
|
||||
assert(!is_null(), "Must be created");
|
||||
return NativeAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(_obj);
|
||||
}
|
||||
|
||||
template <WeakHandleType T>
|
||||
void WeakHandle<T>::replace(oop with_obj) {
|
||||
inline void WeakHandle::replace(oop with_obj) {
|
||||
NativeAccess<ON_PHANTOM_OOP_REF>::oop_store(_obj, with_obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ typedef ConcurrentHashTable<ResolvedMethodTableConfig,
|
|||
class ResolvedMethodTableConfig : public AllStatic {
|
||||
private:
|
||||
public:
|
||||
typedef WeakHandle<vm_resolved_method_table_data> Value;
|
||||
typedef WeakHandle Value;
|
||||
|
||||
static uintx get_hash(Value const& value, bool* is_dead) {
|
||||
oop val_oop = value.peek();
|
||||
|
@ -83,7 +83,7 @@ class ResolvedMethodTableConfig : public AllStatic {
|
|||
return AllocateHeap(size, mtClass);
|
||||
}
|
||||
static void free_node(void* memory, Value const& value) {
|
||||
value.release();
|
||||
value.release(OopStorageSet::resolved_method_table_weak());
|
||||
FreeHeap(memory);
|
||||
ResolvedMethodTable::item_removed();
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ class ResolvedMethodTableLookup : StackObj {
|
|||
uintx get_hash() const {
|
||||
return _hash;
|
||||
}
|
||||
bool equals(WeakHandle<vm_resolved_method_table_data>* value, bool* is_dead) {
|
||||
bool equals(WeakHandle* value, bool* is_dead) {
|
||||
oop val_oop = value->peek();
|
||||
if (val_oop == NULL) {
|
||||
// dead oop, mark this hash dead for cleaning
|
||||
|
@ -145,7 +145,7 @@ class ResolvedMethodGet : public StackObj {
|
|||
Handle _return;
|
||||
public:
|
||||
ResolvedMethodGet(Thread* thread, const Method* method) : _thread(thread), _method(method) {}
|
||||
void operator()(WeakHandle<vm_resolved_method_table_data>* val) {
|
||||
void operator()(WeakHandle* val) {
|
||||
oop result = val->resolve();
|
||||
assert(result != NULL, "Result should be reachable");
|
||||
_return = Handle(_thread, result);
|
||||
|
@ -193,7 +193,7 @@ oop ResolvedMethodTable::add_method(const Method* method, Handle rmethod_name) {
|
|||
if (_local_table->get(thread, lookup, rmg)) {
|
||||
return rmg.get_res_oop();
|
||||
}
|
||||
WeakHandle<vm_resolved_method_table_data> wh = WeakHandle<vm_resolved_method_table_data>::create(rmethod_name);
|
||||
WeakHandle wh(OopStorageSet::resolved_method_table_weak(), rmethod_name);
|
||||
// The hash table takes ownership of the WeakHandle, even if it's not inserted.
|
||||
if (_local_table->insert(thread, lookup, wh)) {
|
||||
log_insert(method);
|
||||
|
@ -282,7 +282,7 @@ void ResolvedMethodTable::grow(JavaThread* jt) {
|
|||
}
|
||||
|
||||
struct ResolvedMethodTableDoDelete : StackObj {
|
||||
void operator()(WeakHandle<vm_resolved_method_table_data>* val) {
|
||||
void operator()(WeakHandle* val) {
|
||||
/* do nothing */
|
||||
}
|
||||
};
|
||||
|
@ -291,7 +291,7 @@ struct ResolvedMethodTableDeleteCheck : StackObj {
|
|||
long _count;
|
||||
long _item;
|
||||
ResolvedMethodTableDeleteCheck() : _count(0), _item(0) {}
|
||||
bool operator()(WeakHandle<vm_resolved_method_table_data>* val) {
|
||||
bool operator()(WeakHandle* val) {
|
||||
++_item;
|
||||
oop tmp = val->peek();
|
||||
if (tmp == NULL) {
|
||||
|
@ -345,7 +345,7 @@ class AdjustMethodEntries : public StackObj {
|
|||
bool* _trace_name_printed;
|
||||
public:
|
||||
AdjustMethodEntries(bool* trace_name_printed) : _trace_name_printed(trace_name_printed) {};
|
||||
bool operator()(WeakHandle<vm_resolved_method_table_data>* entry) {
|
||||
bool operator()(WeakHandle* entry) {
|
||||
oop mem_name = entry->peek();
|
||||
if (mem_name == NULL) {
|
||||
// Removed
|
||||
|
@ -387,7 +387,7 @@ void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
|
|||
// Verification
|
||||
class VerifyResolvedMethod : StackObj {
|
||||
public:
|
||||
bool operator()(WeakHandle<vm_resolved_method_table_data>* val) {
|
||||
bool operator()(WeakHandle* val) {
|
||||
oop obj = val->peek();
|
||||
if (obj != NULL) {
|
||||
Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(obj);
|
||||
|
|
|
@ -128,7 +128,7 @@ static int literal_size(oop obj) {
|
|||
}
|
||||
}
|
||||
|
||||
static int literal_size(WeakHandle<vm_weak_data> v) {
|
||||
static int literal_size(WeakHandle v) {
|
||||
return literal_size(v.peek());
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ template <class T> void print_literal(T l) {
|
|||
l->print();
|
||||
}
|
||||
|
||||
static void print_literal(WeakHandle<vm_weak_data> l) {
|
||||
static void print_literal(WeakHandle l) {
|
||||
l.print();
|
||||
}
|
||||
|
||||
|
@ -287,14 +287,13 @@ template class Hashtable<ConstantPool*, mtClass>;
|
|||
template class Hashtable<Symbol*, mtSymbol>;
|
||||
template class Hashtable<Klass*, mtClass>;
|
||||
template class Hashtable<InstanceKlass*, mtClass>;
|
||||
template class Hashtable<WeakHandle<vm_weak_data>, mtClass>;
|
||||
template class Hashtable<WeakHandle, mtClass>;
|
||||
template class Hashtable<Symbol*, mtModule>;
|
||||
template class Hashtable<oop, mtSymbol>;
|
||||
template class Hashtable<Symbol*, mtClass>;
|
||||
template class HashtableEntry<Symbol*, mtSymbol>;
|
||||
template class HashtableEntry<Symbol*, mtClass>;
|
||||
template class HashtableEntry<oop, mtSymbol>;
|
||||
template class HashtableEntry<WeakHandle<vm_weak_data>, mtClass>;
|
||||
template class HashtableBucket<mtClass>;
|
||||
template class BasicHashtableEntry<mtSymbol>;
|
||||
template class BasicHashtableEntry<mtCode>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue