Mercurial > hg > graal-jvmci-8
diff src/share/vm/classfile/classFileParser.cpp @ 4731:4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
Summary: Change ClassFileParser::parseClassFile() to use the instanceKlass:_cached_class_file_bytes field to avoid leaking the cache.
Reviewed-by: coleenp, acorn, poonam
author | dcubed |
---|---|
date | Thu, 22 Dec 2011 12:50:42 -0800 |
parents | e6b1331a51d2 |
children | 05de27e852c4 5b58979183f9 |
line wrap: on
line diff
--- a/src/share/vm/classfile/classFileParser.cpp Wed Dec 21 18:22:14 2011 -0800 +++ b/src/share/vm/classfile/classFileParser.cpp Thu Dec 22 12:50:42 2011 -0800 @@ -45,6 +45,7 @@ #include "oops/methodOop.hpp" #include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" +#include "prims/jvmtiThreadState.hpp" #include "runtime/javaCalls.hpp" #include "runtime/perfData.hpp" #include "runtime/reflection.hpp" @@ -2639,8 +2640,11 @@ TempNewSymbol& parsed_name, bool verify, TRAPS) { - // So that JVMTI can cache class file in the state before retransformable agents - // have modified it + // When a retransformable agent is attached, JVMTI caches the + // class bytes that existed before the first retransformation. + // 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; @@ -2660,6 +2664,20 @@ _max_bootstrap_specifier_index = -1; if (JvmtiExport::should_post_class_file_load_hook()) { + // Get the cached class file bytes (if any) from the + // class that is being redefined. + JvmtiThreadState *state = JvmtiThreadState::state_for(jt); + KlassHandle *h_class_being_redefined = + state->get_class_being_redefined(); + 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(); + } + unsigned char* ptr = cfs->buffer(); unsigned char* end_ptr = cfs->buffer() + cfs->length();