OpenJDK / valhalla / valhalla10-old / hotspot
changeset 8493:0e1f666bf724
8081320: Backout JDK-8059340: ConstantPool::_resolved_references is missing in heap dump
Reviewed-by: sspitsyn, coleenp
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Fri May 29 17:04:21 2015 +0300 @@ -229,21 +229,16 @@ Register tmp = index; // reuse lslw(tmp, tmp, LogBytesPerHeapOop); + get_constant_pool(result); // load pointer for resolved_references[] objArray - get_resolved_references(result); + ldr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes())); + // JNIHandles::resolve(obj); + ldr(result, Address(result, 0)); // Add in the index add(result, result, tmp); load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); } -void InterpreterMacroAssembler::get_resolved_references(Register reg) { - get_constant_pool(reg); - ldr(reg, Address(reg, ConstantPool::pool_holder_offset_in_bytes())); - ldr(reg, Address(reg, Klass::java_mirror_offset())); - assert(java_lang_Class::resolved_references_offset_in_bytes() > 0, ""); - load_heap_oop(reg, Address(reg, java_lang_Class::resolved_references_offset_in_bytes())); -} - // Generate a subtype check: branch to ok_is_subtype if sub_klass is a // subtype of super_klass. //
--- a/src/cpu/aarch64/vm/interp_masm_aarch64.hpp Fri May 29 12:49:31 2015 +0200 +++ b/src/cpu/aarch64/vm/interp_masm_aarch64.hpp Fri May 29 17:04:21 2015 +0300 @@ -121,8 +121,6 @@ ldr(tags, Address(cpool, ConstantPool::tags_offset_in_bytes())); } - void get_resolved_references(Register reg); - void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2)); void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Fri May 29 17:04:21 2015 +0300 @@ -798,8 +798,11 @@ // word index to byte offset. Since this is a java object, it can be compressed Register tmp = index; // reuse sll(index, LogBytesPerHeapOop, tmp); + get_constant_pool(result); // load pointer for resolved_references[] objArray - get_resolved_references(result); + ld_ptr(result, ConstantPool::resolved_references_offset_in_bytes(), result); + // JNIHandles::resolve(result) + ld_ptr(result, 0, result); // Add in the index add(result, tmp, result); load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result); @@ -970,13 +973,6 @@ ld_ptr(Rcpool, ConstantPool::tags_offset_in_bytes(), Rtags); } -void InterpreterMacroAssembler::get_resolved_references(Register Rdst) { - get_constant_pool(Rdst); - ld_ptr(Rdst, ConstantPool::pool_holder_offset_in_bytes(), Rdst); - ld_ptr(Rdst, Klass::java_mirror_offset(), Rdst); - assert(java_lang_Class::resolved_references_offset_in_bytes() > 0, ""); - load_heap_oop(Rdst, java_lang_Class::resolved_references_offset_in_bytes(), Rdst); -} // unlock if synchronized method //
--- a/src/cpu/sparc/vm/interp_masm_sparc.hpp Fri May 29 12:49:31 2015 +0200 +++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp Fri May 29 17:04:21 2015 +0300 @@ -212,7 +212,6 @@ void get_constant_pool(Register Rdst); void get_constant_pool_cache(Register Rdst); void get_cpool_and_tags(Register Rcpool, Register Rtags); - void get_resolved_references(Register Rdst); void is_a(Label& L); // Load compiled (i2c) or interpreter entry and call from interpreted
--- a/src/cpu/x86/vm/interp_masm_x86.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/cpu/x86/vm/interp_masm_x86.cpp Fri May 29 17:04:21 2015 +0300 @@ -482,14 +482,6 @@ andl(bytecode, ConstantPoolCacheEntry::bytecode_1_mask); } -void InterpreterMacroAssembler::get_resolved_references(Register reg) { - get_constant_pool(reg); - movptr(reg, Address(reg, ConstantPool::pool_holder_offset_in_bytes())); - movptr(reg, Address(reg, Klass::java_mirror_offset())); - assert(java_lang_Class::resolved_references_offset_in_bytes() > 0, ""); - load_heap_oop(reg, Address(reg, java_lang_Class::resolved_references_offset_in_bytes())); -} - void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, @@ -507,16 +499,20 @@ addptr(cache, tmp); // construct pointer to cache entry } -// Load object from cpool->pool_holder->mirror->resolved_references(index) -void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index) { +// Load object from cpool->resolved_references(index) +void InterpreterMacroAssembler::load_resolved_reference_at_index( + Register result, Register index) { assert_different_registers(result, 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 Register tmp = index; // reuse shll(tmp, LogBytesPerHeapOop); + get_constant_pool(result); // load pointer for resolved_references[] objArray - get_resolved_references(result); + movptr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes())); + // JNIHandles::resolve(obj); + movptr(result, Address(result, 0)); // Add in the index addptr(result, tmp); load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
--- a/src/cpu/x86/vm/interp_masm_x86.hpp Fri May 29 12:49:31 2015 +0200 +++ b/src/cpu/x86/vm/interp_masm_x86.hpp Fri May 29 17:04:21 2015 +0300 @@ -109,8 +109,6 @@ movptr(tags, Address(cpool, ConstantPool::tags_offset_in_bytes())); } - void get_resolved_references(Register reg); - void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); void get_cache_and_index_at_bcp(Register cache, Register index,
--- a/src/share/vm/ci/ciStreams.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/ci/ciStreams.cpp Fri May 29 17:04:21 2015 +0300 @@ -477,8 +477,10 @@ // ------------------------------------------------------------------ // ciBytecodeStream::get_resolved_references ciObjArray* ciBytecodeStream::get_resolved_references() { - VM_ENTRY_MARK; - objArrayOop resolved_references = _holder->get_instanceKlass()->resolved_references(); + VM_ENTRY_MARK; + // Get the constant pool. + ConstantPool* cpool = _holder->get_instanceKlass()->constants(); + // Create a resolved references array and return it. - return CURRENT_ENV->get_object(resolved_references)->as_obj_array(); -} + return CURRENT_ENV->get_object(cpool->resolved_references())->as_obj_array(); + }
--- a/src/share/vm/classfile/classLoaderData.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/classfile/classLoaderData.cpp Fri May 29 17:04:21 2015 +0300 @@ -60,6 +60,7 @@ #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.inline.hpp" +#include "runtime/jniHandles.hpp" #include "runtime/mutex.hpp" #include "runtime/safepoint.hpp" #include "runtime/synchronizer.hpp" @@ -80,7 +81,7 @@ // The null-class-loader should always be kept alive. _keep_alive(is_anonymous || h_class_loader.is_null()), _metaspace(NULL), _unloading(false), _klasses(NULL), - _claimed(0), _jmethod_ids(NULL), _deallocate_list(NULL), + _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), _next(NULL), _dependencies(dependencies), _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true, Monitor::_safepoint_check_never)) { @@ -114,6 +115,7 @@ f->do_oop(&_class_loader); _dependencies.oops_do(f); + _handles->oops_do(f); if (klass_closure != NULL) { classes_do(klass_closure); } @@ -354,6 +356,11 @@ _metaspace = NULL; // release the metaspace delete m; + // release the handles + if (_handles != NULL) { + JNIHandleBlock::release_block(_handles); + _handles = NULL; + } } // Clear all the JNI handles for methods @@ -413,6 +420,17 @@ return _metaspace; } +JNIHandleBlock* ClassLoaderData::handles() const { return _handles; } +void ClassLoaderData::set_handles(JNIHandleBlock* handles) { _handles = handles; } + +jobject ClassLoaderData::add_handle(Handle h) { + MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); + if (handles() == NULL) { + set_handles(JNIHandleBlock::allocate_block()); + } + return handles()->allocate_handle(h()); +} + // Add this metadata pointer to be freed when it's safe. This is only during // class unloading because Handles might point to this metadata field. void ClassLoaderData::add_to_deallocate_list(Metadata* m) { @@ -481,6 +499,7 @@ p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name()); if (claimed()) out->print(" claimed "); if (is_unloading()) out->print(" unloading "); + out->print(" handles " INTPTR_FORMAT, p2i(handles())); out->cr(); if (metaspace_or_null() != NULL) { out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
--- a/src/share/vm/classfile/classLoaderData.hpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/classfile/classLoaderData.hpp Fri May 29 17:04:21 2015 +0300 @@ -51,6 +51,7 @@ class ClassLoaderData; class JNIMethodBlock; +class JNIHandleBlock; class Metadebug; // GC root for walking class loader data created @@ -172,6 +173,8 @@ // Has to be an int because we cas it. Klass* _klasses; // The classes defined by the class loader. + JNIHandleBlock* _handles; // Handles to constant pool arrays + // These method IDs are created for the class loader and set to NULL when the // class loader is unloaded. They are rarely freed, only for redefine classes // and if they lose a data race in InstanceKlass. @@ -197,6 +200,9 @@ void set_metaspace(Metaspace* m) { _metaspace = m; } + JNIHandleBlock* handles() const; + void set_handles(JNIHandleBlock* handles); + // GC interface. void clear_claimed() { _claimed = 0; } bool claimed() const { return _claimed == 1; } @@ -284,6 +290,7 @@ void verify(); const char* loader_name(); + jobject add_handle(Handle h); void add_class(Klass* k); void remove_class(Klass* k); bool contains_klass(Klass* k);
--- a/src/share/vm/classfile/javaClasses.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/classfile/javaClasses.cpp Fri May 29 17:04:21 2015 +0300 @@ -567,12 +567,6 @@ } } create_mirror(k, Handle(NULL), Handle(NULL), CHECK); - - if (UseSharedSpaces && k->oop_is_instance()) { - // Create resolved_references array in the fresh mirror. - instanceKlassHandle ik(k()); - ik->constants()->restore_unshareable_info(CHECK); - } } void java_lang_Class::initialize_mirror_fields(KlassHandle k, @@ -930,17 +924,6 @@ the_class_mirror->int_field_put(classRedefinedCount_offset, value); } -objArrayOop java_lang_Class::resolved_references(oop java_class) { - assert(java_lang_Class::is_instance(java_class), ""); - assert(resolvedReferences_offset > 0, "must be set"); - return objArrayOop(java_class->obj_field(resolvedReferences_offset)); -} - -void java_lang_Class::set_resolved_references(oop java_class, objArrayOop a) { - assert(java_lang_Class::is_instance(java_class), ""); - assert(resolvedReferences_offset > 0, "must be set"); - java_class->obj_field_put(resolvedReferences_offset, a); -} // Note: JDK1.1 and before had a privateInfo_offset field which was used for the // platform thread structure, and a eetop offset which was used for thread @@ -3198,7 +3181,6 @@ } } -int java_lang_Class::resolvedReferences_offset; int java_lang_Class::_klass_offset; int java_lang_Class::_array_klass_offset; int java_lang_Class::_oop_size_offset; @@ -3354,9 +3336,6 @@ const int x = heapOopSize; const int header = instanceOopDesc::base_offset_in_bytes(); - // Class - java_lang_Class::resolvedReferences_offset = java_lang_Class::hc_resolvedReferences_offset * x + header; - // Throwable Class java_lang_Throwable::backtrace_offset = java_lang_Throwable::hc_backtrace_offset * x + header; java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header; @@ -3555,7 +3534,9 @@ // java.lang.Class - CHECK_OFFSET("java/lang/Class", java_lang_Class, resolvedReferences, "[Ljava/lang/Object;"); + // Fake fields + // CHECK_OFFSET("java/lang/Class", java_lang_Class, klass); // %%% this needs to be checked + // CHECK_OFFSET("java/lang/Class", java_lang_Class, array_klass); // %%% this needs to be checked // java.lang.Throwable
--- a/src/share/vm/classfile/javaClasses.hpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/classfile/javaClasses.hpp Fri May 29 17:04:21 2015 +0300 @@ -226,10 +226,6 @@ class java_lang_Class : AllStatic { friend class VMStructs; - enum { - hc_resolvedReferences_offset = 12 - }; - private: // The fake offsets are added by the class loader when java.lang.Class is loaded @@ -247,7 +243,6 @@ static bool offsets_computed; static int classRedefinedCount_offset; - static int resolvedReferences_offset; static GrowableArray<Klass*>* _fixup_mirror_list; @@ -306,10 +301,6 @@ static int static_oop_field_count(oop java_class); static void set_static_oop_field_count(oop java_class, int size); - static objArrayOop resolved_references(oop java_class); - static void set_resolved_references(oop java_class, objArrayOop a); - static int resolved_references_offset_in_bytes() { return resolvedReferences_offset; } - static GrowableArray<Klass*>* fixup_mirror_list() { return _fixup_mirror_list; }
--- a/src/share/vm/oops/constantPool.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/oops/constantPool.cpp Fri May 29 17:04:21 2015 +0300 @@ -67,6 +67,7 @@ set_tags(NULL); set_cache(NULL); set_reference_map(NULL); + set_resolved_references(NULL); set_operands(NULL); set_pool_holder(NULL); set_flags(0); @@ -103,6 +104,10 @@ unreference_symbols(); } +objArrayOop ConstantPool::resolved_references() const { + return (objArrayOop)JNIHandles::resolve(_resolved_references); +} + // Create resolved_references array and mapping array for original cp indexes // The ldc bytecode was rewritten to have the resolved reference array index so need a way // to map it back for resolving and some unlikely miscellaneous uses. @@ -131,31 +136,30 @@ // Create Java array for holding resolved strings, methodHandles, // methodTypes, invokedynamic and invokehandle appendix objects, etc. - objArrayOop obj_arr = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK); - pool_holder()->set_resolved_references(obj_arr); + objArrayOop stom = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK); + Handle refs_handle (THREAD, (oop)stom); // must handleize. + set_resolved_references(loader_data->add_handle(refs_handle)); } } -objArrayOop ConstantPool::resolved_references() const { - return pool_holder()->resolved_references(); -} - // CDS support. Create a new resolved_references array. void ConstantPool::restore_unshareable_info(TRAPS) { + + // Only create the new resolved references array if it hasn't been attempted before + if (resolved_references() != NULL) return; + // restore the C++ vtable from the shared archive restore_vtable(); - if (pool_holder()->java_mirror() == NULL) return; - - // Only create the new resolved references array if it hasn't been attempted before - if (pool_holder()->resolved_references() != NULL) return; - if (SystemDictionary::Object_klass_loaded()) { // Recreate the object array and add to ClassLoaderData. int map_length = resolved_reference_length(); if (map_length > 0) { - objArrayOop resolved_references = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK); - pool_holder()->set_resolved_references(resolved_references); + objArrayOop stom = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK); + Handle refs_handle (THREAD, (oop)stom); // must handleize. + + ClassLoaderData* loader_data = pool_holder()->class_loader_data(); + set_resolved_references(loader_data->add_handle(refs_handle)); } } } @@ -164,8 +168,9 @@ // Resolved references are not in the shared archive. // Save the length for restoration. It is not necessarily the same length // as reference_map.length() if invokedynamic is saved. - objArrayOop resolved_references = pool_holder()->resolved_references(); - set_resolved_reference_length(resolved_references != NULL ? resolved_references->length() : 0); + set_resolved_reference_length( + resolved_references() != NULL ? resolved_references()->length() : 0); + set_resolved_references(NULL); } int ConstantPool::cp_to_object_index(int cp_index) { @@ -1866,6 +1871,7 @@ st->print_cr(" - holder: " INTPTR_FORMAT, pool_holder()); } st->print_cr(" - cache: " INTPTR_FORMAT, cache()); + st->print_cr(" - resolved_references: " INTPTR_FORMAT, (void *)resolved_references()); st->print_cr(" - reference_map: " INTPTR_FORMAT, reference_map()); for (int index = 1; index < length(); index++) { // Index 0 is unused
--- a/src/share/vm/oops/constantPool.hpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/oops/constantPool.hpp Fri May 29 17:04:21 2015 +0300 @@ -84,6 +84,7 @@ // Array of resolved objects from the constant pool and map from resolved // object index to original constant pool index + jobject _resolved_references; Array<u2>* _reference_map; enum { @@ -190,7 +191,6 @@ // resolved strings, methodHandles and callsite objects from the constant pool objArrayOop resolved_references() const; - // mapping resolved object array indexes to cp indexes and back. int object_to_cp_index(int index) { return _reference_map->at(index); } int cp_to_object_index(int index); @@ -222,6 +222,7 @@ static int tags_offset_in_bytes() { return offset_of(ConstantPool, _tags); } static int cache_offset_in_bytes() { return offset_of(ConstantPool, _cache); } static int pool_holder_offset_in_bytes() { return offset_of(ConstantPool, _pool_holder); } + static int resolved_references_offset_in_bytes() { return offset_of(ConstantPool, _resolved_references); } // Storing constants @@ -770,6 +771,7 @@ private: + void set_resolved_references(jobject s) { _resolved_references = s; } Array<u2>* reference_map() const { return _reference_map; } void set_reference_map(Array<u2>* o) { _reference_map = o; }
--- a/src/share/vm/oops/instanceKlass.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/oops/instanceKlass.cpp Fri May 29 17:04:21 2015 +0300 @@ -2032,6 +2032,7 @@ } void InstanceKlass::remove_unshareable_info() { + Klass::remove_unshareable_info(); // Unlink the class if (is_linked()) { unlink_class(); @@ -2047,8 +2048,6 @@ // do array classes also. array_klasses_do(remove_unshareable_in_class); - - Klass::remove_unshareable_info(); } static void restore_unshareable_in_class(Klass* k, TRAPS) { @@ -3513,11 +3512,3 @@ unsigned char * InstanceKlass::get_cached_class_file_bytes() { return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file); } - -objArrayOop InstanceKlass::resolved_references() const { - return java_lang_Class::resolved_references(java_mirror()); -} - -void InstanceKlass::set_resolved_references(objArrayOop obj_arr) { - return java_lang_Class::set_resolved_references(java_mirror(), obj_arr); -}
--- a/src/share/vm/oops/instanceKlass.hpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/oops/instanceKlass.hpp Fri May 29 17:04:21 2015 +0300 @@ -532,9 +532,6 @@ ConstantPool* constants() const { return _constants; } void set_constants(ConstantPool* c) { _constants = c; } - objArrayOop resolved_references() const; - void set_resolved_references(objArrayOop obj_arr); - // protection domain oop protection_domain() const;
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri May 29 17:04:21 2015 +0300 @@ -3885,10 +3885,7 @@ // Attach new constant pool to the original klass. The original // klass still refers to the old constant pool (for now). - // resolved_references array should be moved as well, since it is located - // in klass mirror. scratch_class->constants()->set_pool_holder(the_class()); - the_class->set_resolved_references(scratch_class->resolved_references()); #if 0 // In theory, with constant pool merging in place we should be able
--- a/src/share/vm/runtime/vmStructs.cpp Fri May 29 12:49:31 2015 +0200 +++ b/src/share/vm/runtime/vmStructs.cpp Fri May 29 17:04:21 2015 +0300 @@ -288,6 +288,7 @@ nonstatic_field(ConstantPool, _pool_holder, InstanceKlass*) \ nonstatic_field(ConstantPool, _operands, Array<u2>*) \ nonstatic_field(ConstantPool, _length, int) \ + nonstatic_field(ConstantPool, _resolved_references, jobject) \ nonstatic_field(ConstantPool, _reference_map, Array<u2>*) \ nonstatic_field(ConstantPoolCache, _length, int) \ nonstatic_field(ConstantPoolCache, _constant_pool, ConstantPool*) \