Wed, 17 Jul 2013 18:06:29 -0400
8020309: Eliminate InstanceKlass::_cached_class_file_len.
Summary: Use JvmtiCachedClassFileData.
Reviewed-by: iklam, sspitsyn, dcubed
1.1 --- a/src/share/vm/classfile/classFileParser.cpp Wed Jun 12 11:17:39 2013 +0200 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Wed Jul 17 18:06:29 2013 -0400 1.3 @@ -3647,8 +3647,7 @@ 1.4 // If RedefineClasses() was used before the retransformable 1.5 // agent attached, then the cached class bytes may not be the 1.6 // original class bytes. 1.7 - unsigned char *cached_class_file_bytes = NULL; 1.8 - jint cached_class_file_length; 1.9 + JvmtiCachedClassFileData *cached_class_file = NULL; 1.10 Handle class_loader(THREAD, loader_data->class_loader()); 1.11 bool has_default_methods = false; 1.12 ResourceMark rm(THREAD); 1.13 @@ -3680,10 +3679,7 @@ 1.14 if (h_class_being_redefined != NULL) { 1.15 instanceKlassHandle ikh_class_being_redefined = 1.16 instanceKlassHandle(THREAD, (*h_class_being_redefined)()); 1.17 - cached_class_file_bytes = 1.18 - ikh_class_being_redefined->get_cached_class_file_bytes(); 1.19 - cached_class_file_length = 1.20 - ikh_class_being_redefined->get_cached_class_file_len(); 1.21 + cached_class_file = ikh_class_being_redefined->get_cached_class_file(); 1.22 } 1.23 } 1.24 1.25 @@ -3691,9 +3687,7 @@ 1.26 unsigned char* end_ptr = cfs->buffer() + cfs->length(); 1.27 1.28 JvmtiExport::post_class_file_load_hook(name, class_loader(), protection_domain, 1.29 - &ptr, &end_ptr, 1.30 - &cached_class_file_bytes, 1.31 - &cached_class_file_length); 1.32 + &ptr, &end_ptr, &cached_class_file); 1.33 1.34 if (ptr != cfs->buffer()) { 1.35 // JVMTI agent has modified class file data. 1.36 @@ -4011,10 +4005,9 @@ 1.37 } 1.38 } 1.39 1.40 - if (cached_class_file_bytes != NULL) { 1.41 + if (cached_class_file != NULL) { 1.42 // JVMTI: we have an InstanceKlass now, tell it about the cached bytes 1.43 - this_klass->set_cached_class_file(cached_class_file_bytes, 1.44 - cached_class_file_length); 1.45 + this_klass->set_cached_class_file(cached_class_file); 1.46 } 1.47 1.48 // Fill in field values obtained by parse_classfile_attributes
2.1 --- a/src/share/vm/oops/instanceKlass.cpp Wed Jun 12 11:17:39 2013 +0200 2.2 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Jul 17 18:06:29 2013 -0400 2.3 @@ -48,6 +48,7 @@ 2.4 #include "oops/symbol.hpp" 2.5 #include "prims/jvmtiExport.hpp" 2.6 #include "prims/jvmtiRedefineClassesTrace.hpp" 2.7 +#include "prims/jvmtiRedefineClasses.hpp" 2.8 #include "prims/methodComparator.hpp" 2.9 #include "runtime/fieldDescriptor.hpp" 2.10 #include "runtime/handles.inline.hpp" 2.11 @@ -291,7 +292,7 @@ 2.12 set_initial_method_idnum(0); 2.13 _dependencies = NULL; 2.14 set_jvmti_cached_class_field_map(NULL); 2.15 - set_cached_class_file(NULL, 0); 2.16 + set_cached_class_file(NULL); 2.17 set_initial_method_idnum(0); 2.18 set_minor_version(0); 2.19 set_major_version(0); 2.20 @@ -2357,10 +2358,9 @@ 2.21 } 2.22 2.23 // deallocate the cached class file 2.24 - if (_cached_class_file_bytes != NULL) { 2.25 - os::free(_cached_class_file_bytes, mtClass); 2.26 - _cached_class_file_bytes = NULL; 2.27 - _cached_class_file_len = 0; 2.28 + if (_cached_class_file != NULL) { 2.29 + os::free(_cached_class_file, mtClass); 2.30 + _cached_class_file = NULL; 2.31 } 2.32 2.33 // Decrement symbol reference counts associated with the unloaded class. 2.34 @@ -3530,6 +3530,14 @@ 2.35 return m; 2.36 } 2.37 2.38 +jint InstanceKlass::get_cached_class_file_len() { 2.39 + return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file); 2.40 +} 2.41 + 2.42 +unsigned char * InstanceKlass::get_cached_class_file_bytes() { 2.43 + return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file); 2.44 +} 2.45 + 2.46 2.47 // Construct a PreviousVersionNode entry for the array hung off 2.48 // the InstanceKlass.
3.1 --- a/src/share/vm/oops/instanceKlass.hpp Wed Jun 12 11:17:39 2013 +0200 3.2 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Jul 17 18:06:29 2013 -0400 3.3 @@ -133,6 +133,8 @@ 3.4 uint _count; 3.5 }; 3.6 3.7 +struct JvmtiCachedClassFileData; 3.8 + 3.9 class InstanceKlass: public Klass { 3.10 friend class VMStructs; 3.11 friend class ClassFileParser; 3.12 @@ -249,8 +251,8 @@ 3.13 // InstanceKlass. See PreviousVersionWalker below. 3.14 GrowableArray<PreviousVersionNode *>* _previous_versions; 3.15 // JVMTI fields can be moved to their own structure - see 6315920 3.16 - unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH 3.17 - jint _cached_class_file_len; // JVMTI: length of above 3.18 + // JVMTI: cached class file, before retransformable agent modified it in CFLH 3.19 + JvmtiCachedClassFileData* _cached_class_file; 3.20 3.21 volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change 3.22 3.23 @@ -615,11 +617,12 @@ 3.24 static void purge_previous_versions(InstanceKlass* ik); 3.25 3.26 // JVMTI: Support for caching a class file before it is modified by an agent that can do retransformation 3.27 - void set_cached_class_file(unsigned char *class_file_bytes, 3.28 - jint class_file_len) { _cached_class_file_len = class_file_len; 3.29 - _cached_class_file_bytes = class_file_bytes; } 3.30 - jint get_cached_class_file_len() { return _cached_class_file_len; } 3.31 - unsigned char * get_cached_class_file_bytes() { return _cached_class_file_bytes; } 3.32 + void set_cached_class_file(JvmtiCachedClassFileData *data) { 3.33 + _cached_class_file = data; 3.34 + } 3.35 + JvmtiCachedClassFileData * get_cached_class_file() { return _cached_class_file; } 3.36 + jint get_cached_class_file_len(); 3.37 + unsigned char * get_cached_class_file_bytes(); 3.38 3.39 // JVMTI: Support for caching of field indices, types, and offsets 3.40 void set_jvmti_cached_class_field_map(JvmtiCachedClassFieldMap* descriptor) {
4.1 --- a/src/share/vm/prims/jvmtiExport.cpp Wed Jun 12 11:17:39 2013 +0200 4.2 +++ b/src/share/vm/prims/jvmtiExport.cpp Wed Jul 17 18:06:29 2013 -0400 4.3 @@ -41,6 +41,7 @@ 4.4 #include "prims/jvmtiRawMonitor.hpp" 4.5 #include "prims/jvmtiTagMap.hpp" 4.6 #include "prims/jvmtiThreadState.inline.hpp" 4.7 +#include "prims/jvmtiRedefineClasses.hpp" 4.8 #include "runtime/arguments.hpp" 4.9 #include "runtime/handles.hpp" 4.10 #include "runtime/interfaceSupport.hpp" 4.11 @@ -516,8 +517,7 @@ 4.12 jint _curr_len; 4.13 unsigned char * _curr_data; 4.14 JvmtiEnv * _curr_env; 4.15 - jint * _cached_length_ptr; 4.16 - unsigned char ** _cached_data_ptr; 4.17 + JvmtiCachedClassFileData ** _cached_class_file_ptr; 4.18 JvmtiThreadState * _state; 4.19 KlassHandle * _h_class_being_redefined; 4.20 JvmtiClassLoadKind _load_kind; 4.21 @@ -526,8 +526,7 @@ 4.22 inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader, 4.23 Handle h_protection_domain, 4.24 unsigned char **data_ptr, unsigned char **end_ptr, 4.25 - unsigned char **cached_data_ptr, 4.26 - jint *cached_length_ptr) { 4.27 + JvmtiCachedClassFileData **cache_ptr) { 4.28 _h_name = h_name; 4.29 _class_loader = class_loader; 4.30 _h_protection_domain = h_protection_domain; 4.31 @@ -537,8 +536,7 @@ 4.32 _curr_len = *end_ptr - *data_ptr; 4.33 _curr_data = *data_ptr; 4.34 _curr_env = NULL; 4.35 - _cached_length_ptr = cached_length_ptr; 4.36 - _cached_data_ptr = cached_data_ptr; 4.37 + _cached_class_file_ptr = cache_ptr; 4.38 4.39 _state = _thread->jvmti_thread_state(); 4.40 if (_state != NULL) { 4.41 @@ -615,15 +613,20 @@ 4.42 } 4.43 if (new_data != NULL) { 4.44 // this agent has modified class data. 4.45 - if (caching_needed && *_cached_data_ptr == NULL) { 4.46 + if (caching_needed && *_cached_class_file_ptr == NULL) { 4.47 // data has been changed by the new retransformable agent 4.48 // and it hasn't already been cached, cache it 4.49 - *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len, mtInternal); 4.50 - if (*_cached_data_ptr == NULL) { 4.51 - vm_exit_out_of_memory(_curr_len, OOM_MALLOC_ERROR, "unable to allocate cached copy of original class bytes"); 4.52 + JvmtiCachedClassFileData *p; 4.53 + p = (JvmtiCachedClassFileData *)os::malloc( 4.54 + offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal); 4.55 + if (p == NULL) { 4.56 + vm_exit_out_of_memory(offset_of(JvmtiCachedClassFileData, data) + _curr_len, 4.57 + OOM_MALLOC_ERROR, 4.58 + "unable to allocate cached copy of original class bytes"); 4.59 } 4.60 - memcpy(*_cached_data_ptr, _curr_data, _curr_len); 4.61 - *_cached_length_ptr = _curr_len; 4.62 + p->length = _curr_len; 4.63 + memcpy(p->data, _curr_data, _curr_len); 4.64 + *_cached_class_file_ptr = p; 4.65 } 4.66 4.67 if (_curr_data != *_data_ptr) { 4.68 @@ -662,13 +665,11 @@ 4.69 Handle h_protection_domain, 4.70 unsigned char **data_ptr, 4.71 unsigned char **end_ptr, 4.72 - unsigned char **cached_data_ptr, 4.73 - jint *cached_length_ptr) { 4.74 + JvmtiCachedClassFileData **cache_ptr) { 4.75 JvmtiClassFileLoadHookPoster poster(h_name, class_loader, 4.76 h_protection_domain, 4.77 data_ptr, end_ptr, 4.78 - cached_data_ptr, 4.79 - cached_length_ptr); 4.80 + cache_ptr); 4.81 poster.post(); 4.82 } 4.83
5.1 --- a/src/share/vm/prims/jvmtiExport.hpp Wed Jun 12 11:17:39 2013 +0200 5.2 +++ b/src/share/vm/prims/jvmtiExport.hpp Wed Jul 17 18:06:29 2013 -0400 5.3 @@ -323,8 +323,7 @@ 5.4 static void post_class_file_load_hook(Symbol* h_name, Handle class_loader, 5.5 Handle h_protection_domain, 5.6 unsigned char **data_ptr, unsigned char **end_ptr, 5.7 - unsigned char **cached_data_ptr, 5.8 - jint *cached_length_ptr) NOT_JVMTI_RETURN; 5.9 + JvmtiCachedClassFileData **cache_ptr) NOT_JVMTI_RETURN; 5.10 static void post_native_method_bind(Method* method, address* function_ptr) NOT_JVMTI_RETURN; 5.11 static void post_compiled_method_load(nmethod *nm) NOT_JVMTI_RETURN; 5.12 static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) NOT_JVMTI_RETURN;
6.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jun 12 11:17:39 2013 +0200 6.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jul 17 18:06:29 2013 -0400 6.3 @@ -3342,9 +3342,7 @@ 6.4 // should get cleared in the_class too. 6.5 if (the_class->get_cached_class_file_bytes() == 0) { 6.6 // the_class doesn't have a cache yet so copy it 6.7 - the_class->set_cached_class_file( 6.8 - scratch_class->get_cached_class_file_bytes(), 6.9 - scratch_class->get_cached_class_file_len()); 6.10 + the_class->set_cached_class_file(scratch_class->get_cached_class_file()); 6.11 } 6.12 #ifndef PRODUCT 6.13 else { 6.14 @@ -3357,7 +3355,7 @@ 6.15 6.16 // NULL out in scratch class to not delete twice. The class to be redefined 6.17 // always owns these bytes. 6.18 - scratch_class->set_cached_class_file(NULL, 0); 6.19 + scratch_class->set_cached_class_file(NULL); 6.20 6.21 // Replace inner_classes 6.22 Array<u2>* old_inner_classes = the_class->inner_classes();
7.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed Jun 12 11:17:39 2013 +0200 7.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed Jul 17 18:06:29 2013 -0400 7.3 @@ -331,6 +331,11 @@ 7.4 // coordinate a cleanup of these constants with Runtime. 7.5 // 7.6 7.7 +struct JvmtiCachedClassFileData { 7.8 + jint length; 7.9 + unsigned char data[1]; 7.10 +}; 7.11 + 7.12 class VM_RedefineClasses: public VM_Operation { 7.13 private: 7.14 // These static fields are needed by ClassLoaderDataGraph::classes_do() 7.15 @@ -509,5 +514,12 @@ 7.16 // Modifiable test must be shared between IsModifiableClass query 7.17 // and redefine implementation 7.18 static bool is_modifiable_class(oop klass_mirror); 7.19 + 7.20 + static jint get_cached_class_file_len(JvmtiCachedClassFileData *cache) { 7.21 + return cache == NULL ? 0 : cache->length; 7.22 + } 7.23 + static unsigned char * get_cached_class_file_bytes(JvmtiCachedClassFileData *cache) { 7.24 + return cache == NULL ? NULL : cache->data; 7.25 + } 7.26 }; 7.27 #endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES_HPP