--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 17 12:22:57 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 17 17:14:50 2013 -0700
@@ -3647,8 +3647,7 @@
// If RedefineClasses() was used before the retransformable
// agent attached, then the cached class bytes may not be the
// original class bytes.
- unsigned char *cached_class_file_bytes = NULL;
- jint cached_class_file_length;
+ JvmtiCachedClassFileData *cached_class_file = NULL;
Handle class_loader(THREAD, loader_data->class_loader());
bool has_default_methods = false;
ResourceMark rm(THREAD);
@@ -3680,10 +3679,7 @@
if (h_class_being_redefined != NULL) {
instanceKlassHandle ikh_class_being_redefined =
instanceKlassHandle(THREAD, (*h_class_being_redefined)());
- cached_class_file_bytes =
- ikh_class_being_redefined->get_cached_class_file_bytes();
- cached_class_file_length =
- ikh_class_being_redefined->get_cached_class_file_len();
+ cached_class_file = ikh_class_being_redefined->get_cached_class_file();
}
}
@@ -3691,9 +3687,7 @@
unsigned char* end_ptr = cfs->buffer() + cfs->length();
JvmtiExport::post_class_file_load_hook(name, class_loader(), protection_domain,
- &ptr, &end_ptr,
- &cached_class_file_bytes,
- &cached_class_file_length);
+ &ptr, &end_ptr, &cached_class_file);
if (ptr != cfs->buffer()) {
// JVMTI agent has modified class file data.
@@ -4011,10 +4005,9 @@
}
}
- if (cached_class_file_bytes != NULL) {
+ if (cached_class_file != NULL) {
// JVMTI: we have an InstanceKlass now, tell it about the cached bytes
- this_klass->set_cached_class_file(cached_class_file_bytes,
- cached_class_file_length);
+ this_klass->set_cached_class_file(cached_class_file);
}
// Fill in field values obtained by parse_classfile_attributes
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 17 12:22:57 2013 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 17 17:14:50 2013 -0700
@@ -48,6 +48,7 @@
#include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
+#include "prims/jvmtiRedefineClasses.hpp"
#include "prims/methodComparator.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
@@ -291,7 +292,7 @@
set_initial_method_idnum(0);
_dependencies = NULL;
set_jvmti_cached_class_field_map(NULL);
- set_cached_class_file(NULL, 0);
+ set_cached_class_file(NULL);
set_initial_method_idnum(0);
set_minor_version(0);
set_major_version(0);
@@ -2357,10 +2358,9 @@
}
// deallocate the cached class file
- if (_cached_class_file_bytes != NULL) {
- os::free(_cached_class_file_bytes, mtClass);
- _cached_class_file_bytes = NULL;
- _cached_class_file_len = 0;
+ if (_cached_class_file != NULL) {
+ os::free(_cached_class_file, mtClass);
+ _cached_class_file = NULL;
}
// Decrement symbol reference counts associated with the unloaded class.
@@ -3530,6 +3530,14 @@
return m;
}
+jint InstanceKlass::get_cached_class_file_len() {
+ return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file);
+}
+
+unsigned char * InstanceKlass::get_cached_class_file_bytes() {
+ return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
+}
+
// Construct a PreviousVersionNode entry for the array hung off
// the InstanceKlass.
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 17 12:22:57 2013 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 17 17:14:50 2013 -0700
@@ -133,6 +133,8 @@
uint _count;
};
+struct JvmtiCachedClassFileData;
+
class InstanceKlass: public Klass {
friend class VMStructs;
friend class ClassFileParser;
@@ -249,8 +251,8 @@
// InstanceKlass. See PreviousVersionWalker below.
GrowableArray<PreviousVersionNode *>* _previous_versions;
// JVMTI fields can be moved to their own structure - see 6315920
- unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH
- jint _cached_class_file_len; // JVMTI: length of above
+ // JVMTI: cached class file, before retransformable agent modified it in CFLH
+ JvmtiCachedClassFileData* _cached_class_file;
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
@@ -615,11 +617,12 @@
static void purge_previous_versions(InstanceKlass* ik);
// JVMTI: Support for caching a class file before it is modified by an agent that can do retransformation
- void set_cached_class_file(unsigned char *class_file_bytes,
- jint class_file_len) { _cached_class_file_len = class_file_len;
- _cached_class_file_bytes = class_file_bytes; }
- jint get_cached_class_file_len() { return _cached_class_file_len; }
- unsigned char * get_cached_class_file_bytes() { return _cached_class_file_bytes; }
+ void set_cached_class_file(JvmtiCachedClassFileData *data) {
+ _cached_class_file = data;
+ }
+ JvmtiCachedClassFileData * get_cached_class_file() { return _cached_class_file; }
+ jint get_cached_class_file_len();
+ unsigned char * get_cached_class_file_bytes();
// JVMTI: Support for caching of field indices, types, and offsets
void set_jvmti_cached_class_field_map(JvmtiCachedClassFieldMap* descriptor) {
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Wed Jul 17 12:22:57 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Wed Jul 17 17:14:50 2013 -0700
@@ -41,6 +41,7 @@
#include "prims/jvmtiRawMonitor.hpp"
#include "prims/jvmtiTagMap.hpp"
#include "prims/jvmtiThreadState.inline.hpp"
+#include "prims/jvmtiRedefineClasses.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.hpp"
#include "runtime/interfaceSupport.hpp"
@@ -516,8 +517,7 @@
jint _curr_len;
unsigned char * _curr_data;
JvmtiEnv * _curr_env;
- jint * _cached_length_ptr;
- unsigned char ** _cached_data_ptr;
+ JvmtiCachedClassFileData ** _cached_class_file_ptr;
JvmtiThreadState * _state;
KlassHandle * _h_class_being_redefined;
JvmtiClassLoadKind _load_kind;
@@ -526,8 +526,7 @@
inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader,
Handle h_protection_domain,
unsigned char **data_ptr, unsigned char **end_ptr,
- unsigned char **cached_data_ptr,
- jint *cached_length_ptr) {
+ JvmtiCachedClassFileData **cache_ptr) {
_h_name = h_name;
_class_loader = class_loader;
_h_protection_domain = h_protection_domain;
@@ -537,8 +536,7 @@
_curr_len = *end_ptr - *data_ptr;
_curr_data = *data_ptr;
_curr_env = NULL;
- _cached_length_ptr = cached_length_ptr;
- _cached_data_ptr = cached_data_ptr;
+ _cached_class_file_ptr = cache_ptr;
_state = _thread->jvmti_thread_state();
if (_state != NULL) {
@@ -615,15 +613,20 @@
}
if (new_data != NULL) {
// this agent has modified class data.
- if (caching_needed && *_cached_data_ptr == NULL) {
+ if (caching_needed && *_cached_class_file_ptr == NULL) {
// data has been changed by the new retransformable agent
// and it hasn't already been cached, cache it
- *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len, mtInternal);
- if (*_cached_data_ptr == NULL) {
- vm_exit_out_of_memory(_curr_len, OOM_MALLOC_ERROR, "unable to allocate cached copy of original class bytes");
+ JvmtiCachedClassFileData *p;
+ p = (JvmtiCachedClassFileData *)os::malloc(
+ offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal);
+ if (p == NULL) {
+ vm_exit_out_of_memory(offset_of(JvmtiCachedClassFileData, data) + _curr_len,
+ OOM_MALLOC_ERROR,
+ "unable to allocate cached copy of original class bytes");
}
- memcpy(*_cached_data_ptr, _curr_data, _curr_len);
- *_cached_length_ptr = _curr_len;
+ p->length = _curr_len;
+ memcpy(p->data, _curr_data, _curr_len);
+ *_cached_class_file_ptr = p;
}
if (_curr_data != *_data_ptr) {
@@ -662,13 +665,11 @@
Handle h_protection_domain,
unsigned char **data_ptr,
unsigned char **end_ptr,
- unsigned char **cached_data_ptr,
- jint *cached_length_ptr) {
+ JvmtiCachedClassFileData **cache_ptr) {
JvmtiClassFileLoadHookPoster poster(h_name, class_loader,
h_protection_domain,
data_ptr, end_ptr,
- cached_data_ptr,
- cached_length_ptr);
+ cache_ptr);
poster.post();
}
--- a/hotspot/src/share/vm/prims/jvmtiExport.hpp Wed Jul 17 12:22:57 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.hpp Wed Jul 17 17:14:50 2013 -0700
@@ -323,8 +323,7 @@
static void post_class_file_load_hook(Symbol* h_name, Handle class_loader,
Handle h_protection_domain,
unsigned char **data_ptr, unsigned char **end_ptr,
- unsigned char **cached_data_ptr,
- jint *cached_length_ptr) NOT_JVMTI_RETURN;
+ JvmtiCachedClassFileData **cache_ptr) NOT_JVMTI_RETURN;
static void post_native_method_bind(Method* method, address* function_ptr) NOT_JVMTI_RETURN;
static void post_compiled_method_load(nmethod *nm) NOT_JVMTI_RETURN;
static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) NOT_JVMTI_RETURN;
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jul 17 12:22:57 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jul 17 17:14:50 2013 -0700
@@ -3342,9 +3342,7 @@
// should get cleared in the_class too.
if (the_class->get_cached_class_file_bytes() == 0) {
// the_class doesn't have a cache yet so copy it
- the_class->set_cached_class_file(
- scratch_class->get_cached_class_file_bytes(),
- scratch_class->get_cached_class_file_len());
+ the_class->set_cached_class_file(scratch_class->get_cached_class_file());
}
#ifndef PRODUCT
else {
@@ -3357,7 +3355,7 @@
// NULL out in scratch class to not delete twice. The class to be redefined
// always owns these bytes.
- scratch_class->set_cached_class_file(NULL, 0);
+ scratch_class->set_cached_class_file(NULL);
// Replace inner_classes
Array<u2>* old_inner_classes = the_class->inner_classes();
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed Jul 17 12:22:57 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed Jul 17 17:14:50 2013 -0700
@@ -331,6 +331,11 @@
// coordinate a cleanup of these constants with Runtime.
//
+struct JvmtiCachedClassFileData {
+ jint length;
+ unsigned char data[1];
+};
+
class VM_RedefineClasses: public VM_Operation {
private:
// These static fields are needed by ClassLoaderDataGraph::classes_do()
@@ -509,5 +514,12 @@
// Modifiable test must be shared between IsModifiableClass query
// and redefine implementation
static bool is_modifiable_class(oop klass_mirror);
+
+ static jint get_cached_class_file_len(JvmtiCachedClassFileData *cache) {
+ return cache == NULL ? 0 : cache->length;
+ }
+ static unsigned char * get_cached_class_file_bytes(JvmtiCachedClassFileData *cache) {
+ return cache == NULL ? NULL : cache->data;
+ }
};
#endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES_HPP