mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-15 08:34:30 +02:00
8059340: ConstantPool::_resolved_references is missing in heap dump
Reviewed-by: sspitsyn, stefank, twisti
This commit is contained in:
parent
e5a92a9fb9
commit
3f096651f3
17 changed files with 101 additions and 77 deletions
|
@ -229,16 +229,21 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
|||
Register tmp = index; // reuse
|
||||
lslw(tmp, tmp, LogBytesPerHeapOop);
|
||||
|
||||
get_constant_pool(result);
|
||||
// load pointer for resolved_references[] objArray
|
||||
ldr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
|
||||
// JNIHandles::resolve(obj);
|
||||
ldr(result, Address(result, 0));
|
||||
get_resolved_references(result);
|
||||
// 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.
|
||||
//
|
||||
|
|
|
@ -121,6 +121,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
|||
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));
|
||||
|
|
|
@ -798,11 +798,8 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
|||
// 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
|
||||
ld_ptr(result, ConstantPool::resolved_references_offset_in_bytes(), result);
|
||||
// JNIHandles::resolve(result)
|
||||
ld_ptr(result, 0, result);
|
||||
get_resolved_references(result);
|
||||
// Add in the index
|
||||
add(result, tmp, result);
|
||||
load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
|
||||
|
@ -973,6 +970,13 @@ void InterpreterMacroAssembler::get_cpool_and_tags(Register Rcpool, Register Rta
|
|||
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
|
||||
//
|
||||
|
|
|
@ -212,6 +212,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
|||
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
|
||||
|
|
|
@ -482,6 +482,14 @@ void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register
|
|||
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,
|
||||
|
@ -499,20 +507,16 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
|
|||
addptr(cache, tmp); // construct pointer to cache entry
|
||||
}
|
||||
|
||||
// Load object from cpool->resolved_references(index)
|
||||
void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
||||
Register result, Register index) {
|
||||
// Load object from cpool->pool_holder->mirror->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
|
||||
movptr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
|
||||
// JNIHandles::resolve(obj);
|
||||
movptr(result, Address(result, 0));
|
||||
get_resolved_references(result);
|
||||
// Add in the index
|
||||
addptr(result, tmp);
|
||||
load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
|
||||
|
|
|
@ -109,6 +109,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
|||
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,
|
||||
|
|
|
@ -477,10 +477,8 @@ int ciBytecodeStream::get_method_signature_index() {
|
|||
// ------------------------------------------------------------------
|
||||
// ciBytecodeStream::get_resolved_references
|
||||
ciObjArray* ciBytecodeStream::get_resolved_references() {
|
||||
VM_ENTRY_MARK;
|
||||
// Get the constant pool.
|
||||
ConstantPool* cpool = _holder->get_instanceKlass()->constants();
|
||||
|
||||
VM_ENTRY_MARK;
|
||||
objArrayOop resolved_references = _holder->get_instanceKlass()->resolved_references();
|
||||
// Create a resolved references array and return it.
|
||||
return CURRENT_ENV->get_object(cpool->resolved_references())->as_obj_array();
|
||||
}
|
||||
return CURRENT_ENV->get_object(resolved_references)->as_obj_array();
|
||||
}
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
#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"
|
||||
|
@ -81,7 +80,7 @@ ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Depen
|
|||
// 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), _handles(NULL), _deallocate_list(NULL),
|
||||
_claimed(0), _jmethod_ids(NULL), _deallocate_list(NULL),
|
||||
_next(NULL), _dependencies(dependencies),
|
||||
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
|
||||
Monitor::_safepoint_check_never)) {
|
||||
|
@ -115,7 +114,6 @@ void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool m
|
|||
|
||||
f->do_oop(&_class_loader);
|
||||
_dependencies.oops_do(f);
|
||||
_handles->oops_do(f);
|
||||
if (klass_closure != NULL) {
|
||||
classes_do(klass_closure);
|
||||
}
|
||||
|
@ -356,11 +354,6 @@ ClassLoaderData::~ClassLoaderData() {
|
|||
_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
|
||||
|
@ -420,17 +413,6 @@ Metaspace* ClassLoaderData::metaspace_non_null() {
|
|||
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) {
|
||||
|
@ -499,7 +481,6 @@ void ClassLoaderData::dump(outputStream * const out) {
|
|||
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()));
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
|
||||
class ClassLoaderData;
|
||||
class JNIMethodBlock;
|
||||
class JNIHandleBlock;
|
||||
class Metadebug;
|
||||
|
||||
// GC root for walking class loader data created
|
||||
|
@ -173,8 +172,6 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||
// 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.
|
||||
|
@ -200,9 +197,6 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||
|
||||
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; }
|
||||
|
@ -290,7 +284,6 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||
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);
|
||||
|
|
|
@ -567,6 +567,12 @@ void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
|
|||
}
|
||||
}
|
||||
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,
|
||||
|
@ -924,6 +930,17 @@ void java_lang_Class::set_classRedefinedCount(oop the_class_mirror, int value) {
|
|||
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
|
||||
|
@ -3181,6 +3198,7 @@ bool java_lang_System::has_security_manager() {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -3336,6 +3354,9 @@ void JavaClasses::compute_hard_coded_offsets() {
|
|||
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;
|
||||
|
@ -3534,9 +3555,7 @@ void JavaClasses::check_offsets() {
|
|||
|
||||
// java.lang.Class
|
||||
|
||||
// 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
|
||||
CHECK_OFFSET("java/lang/Class", java_lang_Class, resolvedReferences, "[Ljava/lang/Object;");
|
||||
|
||||
// java.lang.Throwable
|
||||
|
||||
|
|
|
@ -226,6 +226,10 @@ class java_lang_String : AllStatic {
|
|||
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
|
||||
|
||||
|
@ -243,6 +247,7 @@ class java_lang_Class : AllStatic {
|
|||
|
||||
static bool offsets_computed;
|
||||
static int classRedefinedCount_offset;
|
||||
static int resolvedReferences_offset;
|
||||
|
||||
static GrowableArray<Klass*>* _fixup_mirror_list;
|
||||
|
||||
|
@ -301,6 +306,10 @@ class java_lang_Class : AllStatic {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ ConstantPool::ConstantPool(Array<u1>* tags) {
|
|||
set_tags(NULL);
|
||||
set_cache(NULL);
|
||||
set_reference_map(NULL);
|
||||
set_resolved_references(NULL);
|
||||
set_operands(NULL);
|
||||
set_pool_holder(NULL);
|
||||
set_flags(0);
|
||||
|
@ -104,10 +103,6 @@ void ConstantPool::release_C_heap_structures() {
|
|||
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.
|
||||
|
@ -136,30 +131,31 @@ void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
|
|||
|
||||
// Create Java array for holding resolved strings, methodHandles,
|
||||
// methodTypes, invokedynamic and invokehandle appendix objects, etc.
|
||||
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 obj_arr = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);
|
||||
pool_holder()->set_resolved_references(obj_arr);
|
||||
}
|
||||
}
|
||||
|
||||
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 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));
|
||||
objArrayOop resolved_references = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);
|
||||
pool_holder()->set_resolved_references(resolved_references);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,9 +164,8 @@ void ConstantPool::remove_unshareable_info() {
|
|||
// 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.
|
||||
set_resolved_reference_length(
|
||||
resolved_references() != NULL ? resolved_references()->length() : 0);
|
||||
set_resolved_references(NULL);
|
||||
objArrayOop resolved_references = pool_holder()->resolved_references();
|
||||
set_resolved_reference_length(resolved_references != NULL ? resolved_references->length() : 0);
|
||||
}
|
||||
|
||||
int ConstantPool::cp_to_object_index(int cp_index) {
|
||||
|
@ -1871,7 +1866,6 @@ void ConstantPool::print_on(outputStream* st) const {
|
|||
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
|
||||
|
|
|
@ -84,7 +84,6 @@ class ConstantPool : public Metadata {
|
|||
|
||||
// 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 {
|
||||
|
@ -191,6 +190,7 @@ class ConstantPool : public Metadata {
|
|||
|
||||
// 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,7 +222,6 @@ class ConstantPool : public Metadata {
|
|||
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
|
||||
|
||||
|
@ -771,7 +770,6 @@ class ConstantPool : public Metadata {
|
|||
|
||||
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; }
|
||||
|
||||
|
|
|
@ -2032,7 +2032,6 @@ static void remove_unshareable_in_class(Klass* k) {
|
|||
}
|
||||
|
||||
void InstanceKlass::remove_unshareable_info() {
|
||||
Klass::remove_unshareable_info();
|
||||
// Unlink the class
|
||||
if (is_linked()) {
|
||||
unlink_class();
|
||||
|
@ -2048,6 +2047,8 @@ void InstanceKlass::remove_unshareable_info() {
|
|||
|
||||
// do array classes also.
|
||||
array_klasses_do(remove_unshareable_in_class);
|
||||
|
||||
Klass::remove_unshareable_info();
|
||||
}
|
||||
|
||||
static void restore_unshareable_in_class(Klass* k, TRAPS) {
|
||||
|
@ -3512,3 +3513,11 @@ jint InstanceKlass::get_cached_class_file_len() {
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -532,6 +532,9 @@ class InstanceKlass: public Klass {
|
|||
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;
|
||||
|
||||
|
|
|
@ -3885,7 +3885,10 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
|
|||
|
||||
// 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
|
||||
|
|
|
@ -288,7 +288,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
|
|||
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*) \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue