8186088: ConstantPoolCache::_resolved_references is not a JNIHandle
Summary: Make an OopHandle type to replace jobject to encapsulate these oop pointers in metadata and module entry.
Reviewed-by: sspitsyn, dholmes, jiangli, twisti
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -272,8 +272,7 @@
// load pointer for resolved_references[] objArray
ldr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
ldr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
- // JNIHandles::resolve(obj);
- ldr(result, Address(result, 0));
+ resolve_oop_handle(result);
// Add in the index
add(result, result, tmp);
load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -3279,6 +3279,12 @@
}
}
+// ((OopHandle)result).resolve();
+void MacroAssembler::resolve_oop_handle(Register result) {
+ // OopHandle::resolve is an indirection.
+ ldr(result, Address(result, 0));
+}
+
void MacroAssembler::load_mirror(Register dst, Register method) {
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
ldr(dst, Address(rmethod, Method::const_offset()));
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -790,6 +790,7 @@
void store_klass(Register dst, Register src);
void cmp_klass(Register oop, Register trial_klass, Register tmp);
+ void resolve_oop_handle(Register result);
void load_mirror(Register dst, Register method);
void load_heap_oop(Register dst, Address src);
--- a/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -300,8 +300,7 @@
// load pointer for resolved_references[] objArray
ldr(cache, Address(result, ConstantPool::cache_offset_in_bytes()));
ldr(cache, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
- // JNIHandles::resolve(result)
- ldr(cache, Address(cache, 0));
+ resolve_oop_handle(cache);
// Add in the index
// convert from field index to resolved_references() index and from
// word index to byte offset. Since this is a java object, it can be compressed
--- a/hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -2887,6 +2887,11 @@
return offset();
}
+// ((OopHandle)result).resolve();
+void MacroAssembler::resolve_oop_handle(Register result) {
+ // OopHandle::resolve is an indirection.
+ ldr(result, Address(result, 0));
+}
void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
@@ -2896,6 +2901,7 @@
ldr(mirror, Address(tmp, mirror_offset));
}
+
///////////////////////////////////////////////////////////////////////////////
// Compressed pointers
--- a/hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -687,6 +687,7 @@
AbstractAssembler::emit_address((address)L.data());
}
+ void resolve_oop_handle(Register result);
void load_mirror(Register mirror, Register method, Register tmp);
// Porting layer between 32-bit ARM and AArch64
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -464,8 +464,7 @@
// Load pointer for resolved_references[] objArray.
ld(result, ConstantPool::cache_offset_in_bytes(), result);
ld(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
- // JNIHandles::resolve(result)
- ld(result, 0, result);
+ resolve_oop_handle(result);
#ifdef ASSERT
Label index_ok;
lwa(R0, arrayOopDesc::length_offset_in_bytes(), result);
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -3372,6 +3372,12 @@
}
}
+// ((OopHandle)result).resolve();
+void MacroAssembler::resolve_oop_handle(Register result) {
+ // OopHandle::resolve is an indirection.
+ ld(result, 0, result);
+}
+
void MacroAssembler::load_mirror_from_const_method(Register mirror, Register const_method) {
ld(mirror, in_bytes(ConstMethod::constants_offset()), const_method);
ld(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -725,6 +725,7 @@
void store_klass(Register dst_oop, Register klass, Register tmp = R0);
void store_klass_gap(Register dst_oop, Register val = noreg); // Will store 0 if val not specified.
+ void resolve_oop_handle(Register result);
void load_mirror_from_const_method(Register mirror, Register const_method);
static int instr_size_for_decode_klass_not_null();
--- a/hotspot/src/cpu/s390/vm/interp_masm_s390.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/s390/vm/interp_masm_s390.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -364,8 +364,7 @@
// Load pointer for resolved_references[] objArray.
z_lg(result, ConstantPool::cache_offset_in_bytes(), result);
z_lg(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
- // JNIHandles::resolve(result)
- z_lg(result, 0, result); // Load resolved references array itself.
+ resolve_oop_handle(result); // Load resolved references array itself.
#ifdef ASSERT
NearLabel index_ok;
z_lgf(Z_R0, Address(result, arrayOopDesc::length_offset_in_bytes()));
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -4660,6 +4660,12 @@
}
}
+// ((OopHandle)result).resolve();
+void MacroAssembler::resolve_oop_handle(Register result) {
+ // OopHandle::resolve is an indirection.
+ z_lg(result, 0, result);
+}
+
void MacroAssembler::load_mirror(Register mirror, Register method) {
mem2reg_opt(mirror, Address(method, Method::const_offset()));
mem2reg_opt(mirror, Address(mirror, ConstMethod::constants_offset()));
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -832,6 +832,7 @@
void oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL,
Register Rbase = Z_R1, int pow2_offset = -1);
+ void resolve_oop_handle(Register result);
void load_mirror(Register mirror, Register method);
//--------------------------
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -730,8 +730,7 @@
// load pointer for resolved_references[] objArray
ld_ptr(result, ConstantPool::cache_offset_in_bytes(), result);
ld_ptr(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
- // JNIHandles::resolve(result)
- ld_ptr(result, 0, result);
+ resolve_oop_handle(result);
// Add in the index
add(result, tmp, result);
load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -3822,6 +3822,12 @@
card_table_write(bs->byte_map_base, tmp, store_addr);
}
+// ((OopHandle)result).resolve();
+void MacroAssembler::resolve_oop_handle(Register result) {
+ // OopHandle::resolve is an indirection.
+ ld_ptr(result, 0, result);
+}
+
void MacroAssembler::load_mirror(Register mirror, Register method) {
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
ld_ptr(method, in_bytes(Method::const_offset()), mirror);
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -995,6 +995,7 @@
inline void ldbool(const Address& a, Register d);
inline void movbool( bool boolconst, Register d);
+ void resolve_oop_handle(Register result);
void load_mirror(Register mirror, Register method);
// klass oop manipulations if compressed
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -511,8 +511,7 @@
// load pointer for resolved_references[] objArray
movptr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
movptr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
- // JNIHandles::resolve(obj);
- movptr(result, Address(result, 0));
+ resolve_oop_handle(result);
// Add in the index
addptr(result, tmp);
load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -6604,6 +6604,12 @@
#endif // _LP64
}
+// ((OopHandle)result).resolve();
+void MacroAssembler::resolve_oop_handle(Register result) {
+ // OopHandle::resolve is an indirection.
+ movptr(result, Address(result, 0));
+}
+
void MacroAssembler::load_mirror(Register mirror, Register method) {
// get mirror
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
@@ -7030,7 +7036,6 @@
#endif // _LP64
-
// C2 compiled method's prolog code.
void MacroAssembler::verified_entry(int framesize, int stack_bang_size, bool fp_mode_24b) {
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -327,6 +327,7 @@
void movbool(Address dst, Register src);
void testbool(Register dst);
+ void resolve_oop_handle(Register result);
void load_mirror(Register mirror, Register method);
// oop manipulations
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -759,14 +759,18 @@
return metaspace;
}
-jobject ClassLoaderData::add_handle(Handle h) {
+OopHandle ClassLoaderData::add_handle(Handle h) {
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
- return (jobject) _handles.add(h());
+ return OopHandle(_handles.add(h()));
}
-void ClassLoaderData::remove_handle_unsafe(jobject h) {
- assert(_handles.contains((oop*) h), "Got unexpected handle " PTR_FORMAT, p2i((oop*) h));
- *((oop*) h) = NULL;
+void ClassLoaderData::init_handle_locked(OopHandle& dest, Handle h) {
+ MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
+ if (dest.resolve() != NULL) {
+ return;
+ } else {
+ dest = _handles.add(h());
+ }
}
// Add this metadata pointer to be freed when it's safe. This is only during
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -29,6 +29,7 @@
#include "memory/memRegion.hpp"
#include "memory/metaspace.hpp"
#include "memory/metaspaceCounters.hpp"
+#include "oops/oopHandle.hpp"
#include "runtime/mutex.hpp"
#include "trace/traceMacros.hpp"
#include "utilities/growableArray.hpp"
@@ -362,8 +363,8 @@
void verify();
const char* loader_name();
- jobject add_handle(Handle h);
- void remove_handle_unsafe(jobject h);
+ OopHandle add_handle(Handle h);
+ void init_handle_locked(OopHandle& pd, Handle h); // used for concurrent access to ModuleEntry::_pd field
void add_class(Klass* k, bool publicize = true);
void remove_class(Klass* k);
bool contains_klass(Klass* k);
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -799,7 +799,7 @@
// If java.base was already defined then patch this particular class with java.base.
if (javabase_was_defined) {
ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry();
- assert(javabase_entry != NULL && javabase_entry->module_handle() != NULL,
+ assert(javabase_entry != NULL && javabase_entry->module() != NULL,
"Setting class module field, " JAVA_BASE_NAME " should be defined");
Handle javabase_handle(THREAD, javabase_entry->module());
set_module(mirror(), javabase_handle());
--- a/hotspot/src/share/vm/classfile/moduleEntry.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -80,19 +80,16 @@
}
// Returns the shared ProtectionDomain
-Handle ModuleEntry::shared_protection_domain() {
- return Handle(Thread::current(), JNIHandles::resolve(_pd));
+oop ModuleEntry::shared_protection_domain() {
+ return _pd.resolve();
}
// Set the shared ProtectionDomain atomically
void ModuleEntry::set_shared_protection_domain(ClassLoaderData *loader_data,
Handle pd_h) {
// Create a handle for the shared ProtectionDomain and save it atomically.
- // If someone beats us setting the _pd cache, the created handle is destroyed.
- jobject obj = loader_data->add_handle(pd_h);
- if (Atomic::cmpxchg_ptr(obj, &_pd, NULL) != NULL) {
- loader_data->remove_handle_unsafe(obj);
- }
+ // init_handle_locked checks if someone beats us setting the _pd cache.
+ loader_data->init_handle_locked(_pd, pd_h);
}
// Returns true if this module can read module m
--- a/hotspot/src/share/vm/classfile/moduleEntry.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/classfile/moduleEntry.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -27,6 +27,7 @@
#include "classfile/classLoaderData.hpp"
#include "classfile/vmSymbols.hpp"
+#include "oops/oopHandle.hpp"
#include "oops/symbol.hpp"
#include "prims/jni.h"
#include "runtime/jniHandles.hpp"
@@ -56,8 +57,8 @@
// data structure.
class ModuleEntry : public HashtableEntry<Symbol*, mtModule> {
private:
- jobject _module; // java.lang.Module
- jobject _pd; // java.security.ProtectionDomain, cached
+ OopHandle _module; // java.lang.Module
+ OopHandle _pd; // java.security.ProtectionDomain, cached
// for shared classes from this module
ClassLoaderData* _loader_data;
GrowableArray<ModuleEntry*>* _reads; // list of modules that are readable by this module
@@ -89,16 +90,16 @@
Symbol* name() const { return literal(); }
void set_name(Symbol* n) { set_literal(n); }
- oop module() const { return JNIHandles::resolve(_module); }
- jobject module_handle() const { return _module; }
- void set_module(jobject j) { _module = j; }
+ oop module() const { return _module.resolve(); }
+ OopHandle module_handle() const { return _module; }
+ void set_module(OopHandle j) { _module = j; }
// The shared ProtectionDomain reference is set once the VM loads a shared class
// originated from the current Module. The referenced ProtectionDomain object is
// created by the ClassLoader when loading a class (shared or non-shared) from the
// Module for the first time. This ProtectionDomain object is used for all
// classes from the Module loaded by the same ClassLoader.
- Handle shared_protection_domain();
+ oop shared_protection_domain();
void set_shared_protection_domain(ClassLoaderData *loader_data, Handle pd);
ClassLoaderData* loader_data() const { return _loader_data; }
@@ -246,7 +247,7 @@
static void set_javabase_moduleEntry(ModuleEntry* java_base) { _javabase_module = java_base; }
static bool javabase_defined() { return ((_javabase_module != NULL) &&
- (_javabase_module->module_handle() != NULL)); }
+ (_javabase_module->module() != NULL)); }
static void finalize_javabase(Handle module_handle, Symbol* version, Symbol* location);
static void patch_javabase_entries(Handle module_handle);
--- a/hotspot/src/share/vm/oops/constantPool.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -134,7 +134,7 @@
}
objArrayOop ConstantPool::resolved_references() const {
- return (objArrayOop)JNIHandles::resolve(_cache->resolved_references());
+ return (objArrayOop)_cache->resolved_references();
}
// Create resolved_references array and mapping array for original cp indexes
--- a/hotspot/src/share/vm/oops/constantPool.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -28,6 +28,7 @@
#include "oops/arrayOop.hpp"
#include "oops/cpCache.hpp"
#include "oops/objArrayOop.hpp"
+#include "oops/oopHandle.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayOop.hpp"
#include "runtime/handles.hpp"
@@ -821,7 +822,7 @@
private:
- void set_resolved_references(jobject s) { _cache->set_resolved_references(s); }
+ void set_resolved_references(OopHandle s) { _cache->set_resolved_references(s); }
Array<u2>* reference_map() const { return (_cache == NULL) ? NULL : _cache->reference_map(); }
void set_reference_map(Array<u2>* o) { _cache->set_reference_map(o); }
--- a/hotspot/src/share/vm/oops/cpCache.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/oops/cpCache.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -28,6 +28,7 @@
#include "interpreter/bytecodes.hpp"
#include "memory/allocation.hpp"
#include "oops/array.hpp"
+#include "oops/oopHandle.hpp"
#include "runtime/orderAccess.hpp"
#include "utilities/align.hpp"
@@ -413,7 +414,7 @@
// stored in the ConstantPool, which is read-only.
// Array of resolved objects from the constant pool and map from resolved
// object index to original constant pool index
- jobject _resolved_references;
+ OopHandle _resolved_references;
Array<u2>* _reference_map;
// The narrowOop pointer to the archived resolved_references. Set at CDS dump
// time when caching java heap object is supported.
@@ -455,8 +456,8 @@
oop archived_references() NOT_CDS_JAVA_HEAP_RETURN_(NULL);
void set_archived_references(oop o) NOT_CDS_JAVA_HEAP_RETURN;
- jobject resolved_references() { return _resolved_references; }
- void set_resolved_references(jobject s) { _resolved_references = s; }
+ oop resolved_references() { return _resolved_references.resolve(); }
+ void set_resolved_references(OopHandle s) { _resolved_references = s; }
Array<u2>* reference_map() const { return _reference_map; }
void set_reference_map(Array<u2>* o) { _reference_map = o; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/oopHandle.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_OOPHANDLE_HPP
+#define SHARE_VM_OOPS_OOPHANDLE_HPP
+
+#include "oops/oop.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.hpp"
+
+// Simple class for encapsulating oop pointers stored in metadata.
+// These are different from Handle. The Handle class stores pointers
+// to oops on the stack, and manages the allocation from a thread local
+// area in the constructor.
+// This assumes that the caller will allocate the handle in the appropriate
+// area. The reason for the encapsulation is to help with naming and to allow
+// future uses for read barriers.
+
+class OopHandle {
+private:
+ oop* _obj;
+
+public:
+ OopHandle() : _obj(NULL) {}
+ OopHandle(oop* w) : _obj(w) {}
+
+ oop resolve() const { return (_obj == NULL) ? (oop)NULL : *_obj; }
+};
+
+#endif // SHARE_VM_OOPS_OOPHANDLE_HPP
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -1490,14 +1490,14 @@
}
}
-GrowableArray<jobject>* JvmtiModuleClosure::_tbl = NULL;
+GrowableArray<OopHandle>* JvmtiModuleClosure::_tbl = NULL;
jvmtiError
JvmtiModuleClosure::get_all_modules(JvmtiEnv* env, jint* module_count_ptr, jobject** modules_ptr) {
ResourceMark rm;
MutexLocker ml(Module_lock);
- _tbl = new GrowableArray<jobject>(77);
+ _tbl = new GrowableArray<OopHandle>(77);
if (_tbl == NULL) {
return JVMTI_ERROR_OUT_OF_MEMORY;
}
@@ -1513,7 +1513,7 @@
return JVMTI_ERROR_OUT_OF_MEMORY;
}
for (jint idx = 0; idx < len; idx++) {
- array[idx] = _tbl->at(idx);
+ array[idx] = JNIHandles::make_local(Thread::current(), _tbl->at(idx).resolve());
}
_tbl = NULL;
*modules_ptr = array;
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp Wed Aug 23 12:00:39 2017 -0400
@@ -30,6 +30,7 @@
#include "prims/jvmtiEventController.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "prims/jvmtiThreadState.inline.hpp"
+#include "oops/oopHandle.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/frame.hpp"
#include "runtime/handles.inline.hpp"
@@ -704,12 +705,12 @@
// Jvmti module closure to collect all modules loaded to the system.
class JvmtiModuleClosure : public StackObj {
private:
- static GrowableArray<jobject> *_tbl; // Protected with Module_lock
+ static GrowableArray<OopHandle> *_tbl; // Protected with Module_lock
static void do_module(ModuleEntry* entry) {
assert_locked_or_safepoint(Module_lock);
- jobject module = entry->module_handle();
- guarantee(module != NULL, "module object is NULL");
+ OopHandle module = entry->module_handle();
+ guarantee(module.resolve() != NULL, "module object is NULL");
_tbl->push(module);
}
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -764,7 +764,7 @@
ModuleEntry* module_entry = InstanceKlass::cast(klass)->module();
assert(module_entry != NULL, "module_entry should always be set");
if (module_entry->is_named() &&
- module_entry->module_handle() != NULL &&
+ module_entry->module() != NULL &&
!module_entry->has_default_read_edges()) {
if (!module_entry->set_has_default_read_edges()) {
// We won a potential race.
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Aug 23 15:47:41 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Aug 23 12:00:39 2017 -0400
@@ -83,6 +83,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/oopHandle.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayKlass.hpp"
#include "oops/typeArrayOop.hpp"
@@ -235,7 +236,7 @@
nonstatic_field(ConstantPool, _operands, Array<u2>*) \
nonstatic_field(ConstantPool, _resolved_klasses, Array<Klass*>*) \
nonstatic_field(ConstantPool, _length, int) \
- nonstatic_field(ConstantPoolCache, _resolved_references, jobject) \
+ nonstatic_field(ConstantPoolCache, _resolved_references, OopHandle) \
nonstatic_field(ConstantPoolCache, _reference_map, Array<u2>*) \
nonstatic_field(ConstantPoolCache, _length, int) \
nonstatic_field(ConstantPoolCache, _constant_pool, ConstantPool*) \
@@ -1438,6 +1439,7 @@
declare_oop_type(oop) \
declare_oop_type(narrowOop) \
declare_oop_type(typeArrayOop) \
+ declare_oop_type(OopHandle) \
\
/*************************************/ \
/* MethodOop-related data structures */ \