提交 d22a5b73 编写于 作者: J jiangli

8020309: Eliminate InstanceKlass::_cached_class_file_len.

Summary: Use JvmtiCachedClassFileData.
Reviewed-by: iklam, sspitsyn, dcubed
上级 f67fa382
......@@ -3647,8 +3647,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
// 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 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
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 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
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 @@ 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
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
......
......@@ -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 @@ InstanceKlass::InstanceKlass(int vtable_len,
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 @@ void InstanceKlass::release_C_heap_structures() {
}
// 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 @@ Method* InstanceKlass::method_with_idnum(int idnum) {
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.
......
......@@ -133,6 +133,8 @@ class OopMapBlock VALUE_OBJ_CLASS_SPEC {
uint _count;
};
struct JvmtiCachedClassFileData;
class InstanceKlass: public Klass {
friend class VMStructs;
friend class ClassFileParser;
......@@ -249,8 +251,8 @@ class InstanceKlass: public Klass {
// 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 @@ class InstanceKlass: public Klass {
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) {
......
......@@ -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 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
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 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
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 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
_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 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
}
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 @@ void JvmtiExport::post_class_file_load_hook(Symbol* h_name,
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();
}
......
......@@ -323,8 +323,7 @@ class JvmtiExport : public AllStatic {
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;
......
......@@ -3342,9 +3342,7 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// 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 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// 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();
......
......@@ -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 @@ class VM_RedefineClasses: public VM_Operation {
// 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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册