提交 07b44f91 编写于 作者: J jiangli

Merge

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