--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Aug 31 16:39:35 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Sat Sep 01 13:25:18 2012 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -210,28 +210,23 @@
// lazily resolved. Before explaining the copying complication, we need
// to digress into CP entry resolution.
//
-// JVM_CONSTANT_Class and JVM_CONSTANT_String entries are present in
-// the class file, but are not stored in memory as such until they are
-// resolved. The entries are not resolved unless they are used because
-// resolution is expensive. During class file parsing the entries are
-// initially stored in memory as JVM_CONSTANT_ClassIndex and
-// JVM_CONSTANT_StringIndex entries. These special CP entry types
-// indicate that the JVM_CONSTANT_Class and JVM_CONSTANT_String entries
-// have been parsed, but the index values in the entries have not been
+// JVM_CONSTANT_Class entries are present in the class file, but are not
+// stored in memory as such until they are resolved. The entries are not
+// resolved unless they are used because resolution is expensive. During class
+// file parsing the entries are initially stored in memory as
+// JVM_CONSTANT_ClassIndex and JVM_CONSTANT_StringIndex entries. These special
+// CP entry types indicate that the JVM_CONSTANT_Class and JVM_CONSTANT_String
+// entries have been parsed, but the index values in the entries have not been
// validated. After the entire constant pool has been parsed, the index
// values can be validated and then the entries are converted into
-// JVM_CONSTANT_UnresolvedClass and JVM_CONSTANT_UnresolvedString
+// JVM_CONSTANT_UnresolvedClass and JVM_CONSTANT_String
// entries. During this conversion process, the UTF8 values that are
// indirectly referenced by the JVM_CONSTANT_ClassIndex and
// JVM_CONSTANT_StringIndex entries are changed into Symbol*s and the
// entries are modified to refer to the Symbol*s. This optimization
// eliminates one level of indirection for those two CP entry types and
-// gets the entries ready for verification. During class file parsing
-// it is also possible for JVM_CONSTANT_UnresolvedString entries to be
-// resolved into JVM_CONSTANT_String entries. Verification expects to
-// find JVM_CONSTANT_UnresolvedClass and either JVM_CONSTANT_String or
-// JVM_CONSTANT_UnresolvedString entries and not JVM_CONSTANT_Class
-// entries.
+// gets the entries ready for verification. Verification expects to
+// find JVM_CONSTANT_UnresolvedClass but not JVM_CONSTANT_Class entries.
//
// Now we can get back to the copying complication. When we copy
// entries from old_cp to merge_cp, we have to revert any
@@ -260,9 +255,9 @@
// in merge_cp, then the change in index value is tracked.
//
// Note: the above discussion for the direct CP entries also applies
-// to the JVM_CONSTANT_Unresolved{Class,String} entry types.
+// to the JVM_CONSTANT_UnresolvedClass entry types.
//
-// For the JVM_CONSTANT_{Class,String} entry types, since there is only
+// For the JVM_CONSTANT_Class entry types, since there is only
// one data element at the end of the recursion, we know that we have
// either one or two unique entries. If the JVM_CONSTANT_Utf8 entry is
// unique then it is appended to merge_cp before the current entry.
@@ -271,9 +266,9 @@
// appended to merge_cp. Again, any changes in index values are tracked
// as needed.
//
-// Note: the above discussion for JVM_CONSTANT_{Class,String} entry
+// Note: the above discussion for JVM_CONSTANT_Class entry
// types is theoretical. Since those entry types have already been
-// optimized into JVM_CONSTANT_Unresolved{Class,String} entry types,
+// optimized into JVM_CONSTANT_UnresolvedClass entry types,
// they are handled as direct CP entries.
//
// For the JVM_CONSTANT_NameAndType entry type, since there are two
@@ -320,17 +315,11 @@
// 6 bytes. Perhaps Relocator only needs a 4 byte buffer to do
// what it does to the bytecodes. More investigation is needed.
//
-// - java.lang.Object methods can be called on arrays. This is
-// implemented via the arrayKlassOop vtable which we don't
-// update. For example, if we redefine java.lang.Object.toString(),
-// then the new version of the method will not be called for array
-// objects.
-//
// - How do we know if redefine_single_class() and the guts of
-// instanceKlass are out of sync? I don't think this can be
+// InstanceKlass are out of sync? I don't think this can be
// automated, but we should probably order the work in
// redefine_single_class() to match the order of field
-// definitions in instanceKlass. We also need to add some
+// definitions in InstanceKlass. We also need to add some
// comments about keeping things in sync.
//
// - set_new_constant_pool() is huge and we should consider refactoring
@@ -346,16 +335,16 @@
private:
// These static fields are needed by SystemDictionary::classes_do()
// facility and the adjust_cpool_cache_and_vtable() helper:
- static objArrayOop _old_methods;
- static objArrayOop _new_methods;
- static methodOop* _matching_old_methods;
- static methodOop* _matching_new_methods;
- static methodOop* _deleted_methods;
- static methodOop* _added_methods;
+ static Array<Method*>* _old_methods;
+ static Array<Method*>* _new_methods;
+ static Method** _matching_old_methods;
+ static Method** _matching_new_methods;
+ static Method** _deleted_methods;
+ static Method** _added_methods;
static int _matching_methods_length;
static int _deleted_methods_length;
static int _added_methods_length;
- static klassOop _the_class_oop;
+ static Klass* _the_class_oop;
// The instance fields are used to pass information from
// doit_prologue() to doit() and doit_epilogue().
@@ -371,7 +360,7 @@
int _index_map_count;
intArray * _index_map_p;
// ptr to _class_count scratch_classes
- instanceKlassHandle * _scratch_classes;
+ Klass** _scratch_classes;
jvmtiError _res;
// Performance measurement support. These timers do not cover all
@@ -398,7 +387,7 @@
// Swap annotations[i] with annotations[j]
// Used by compare_and_normalize_class_versions() when normalizing
// overloaded methods or changing idnum as when adding or deleting methods.
- void swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class);
+ void swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS);
// Figure out which new methods match old methods in name and signature,
// which methods have been added, and which are no longer present
@@ -421,15 +410,16 @@
// from their constant pool caches, itables, and/or vtables. We
// use the SystemDictionary::classes_do() facility and this helper
// to fix up these pointers.
- static void adjust_cpool_cache_and_vtable(klassOop k_oop, oop loader, TRAPS);
+ static void adjust_cpool_cache_and_vtable(Klass* k_oop, ClassLoaderData* initiating_loader, TRAPS);
+ static void adjust_array_vtable(Klass* k_oop);
// Install the redefinition of a class
void redefine_single_class(jclass the_jclass,
- instanceKlassHandle scratch_class, TRAPS);
+ Klass* scratch_class_oop, TRAPS);
- // Increment the classRedefinedCount field in the specific instanceKlass
+ // Increment the classRedefinedCount field in the specific InstanceKlass
// and in all direct and indirect subclasses.
- void increment_class_counter(instanceKlass *ik, TRAPS);
+ void increment_class_counter(InstanceKlass *ik, TRAPS);
// Support for constant pool merging (these routines are in alpha
// order):
@@ -438,8 +428,6 @@
int find_new_index(int old_index);
bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1,
constantPoolHandle cp2, int index2);
- bool is_unresolved_string_mismatch(constantPoolHandle cp1, int index1,
- constantPoolHandle cp2, int index2);
void map_index(constantPoolHandle scratch_cp, int old_index, int new_index);
bool merge_constant_pools(constantPoolHandle old_cp,
constantPoolHandle scratch_cp, constantPoolHandle *merge_cp_p,
@@ -447,17 +435,17 @@
jvmtiError merge_cp_and_rewrite(instanceKlassHandle the_class,
instanceKlassHandle scratch_class, TRAPS);
u2 rewrite_cp_ref_in_annotation_data(
- typeArrayHandle annotations_typeArray, int &byte_i_ref,
+ AnnotationArray* annotations_typeArray, int &byte_i_ref,
const char * trace_mesg, TRAPS);
bool rewrite_cp_refs(instanceKlassHandle scratch_class, TRAPS);
bool rewrite_cp_refs_in_annotation_struct(
- typeArrayHandle class_annotations, int &byte_i_ref, TRAPS);
+ AnnotationArray* class_annotations, int &byte_i_ref, TRAPS);
bool rewrite_cp_refs_in_annotations_typeArray(
- typeArrayHandle annotations_typeArray, int &byte_i_ref, TRAPS);
+ AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS);
bool rewrite_cp_refs_in_class_annotations(
instanceKlassHandle scratch_class, TRAPS);
bool rewrite_cp_refs_in_element_value(
- typeArrayHandle class_annotations, int &byte_i_ref, TRAPS);
+ AnnotationArray* class_annotations, int &byte_i_ref, TRAPS);
bool rewrite_cp_refs_in_fields_annotations(
instanceKlassHandle scratch_class, TRAPS);
void rewrite_cp_refs_in_method(methodHandle method,
@@ -473,12 +461,13 @@
void rewrite_cp_refs_in_verification_type_info(
address& stackmap_addr_ref, address stackmap_end, u2 frame_i,
u1 frame_size, TRAPS);
- void set_new_constant_pool(instanceKlassHandle scratch_class,
- constantPoolHandle scratch_cp, int scratch_cp_length, bool shrink, TRAPS);
+ void set_new_constant_pool(ClassLoaderData* loader_data,
+ instanceKlassHandle scratch_class,
+ constantPoolHandle scratch_cp, int scratch_cp_length, TRAPS);
void flush_dependent_code(instanceKlassHandle k_h, TRAPS);
- static void check_class(klassOop k_oop, oop initiating_loader, TRAPS) PRODUCT_RETURN;
+ static void check_class(Klass* k_oop, ClassLoaderData* initiating_loader, TRAPS) PRODUCT_RETURN;
static void dump_methods() PRODUCT_RETURN;
@@ -499,4 +488,16 @@
static bool is_modifiable_class(oop klass_mirror);
};
+
+// Helper class to mark and unmark metadata used on the stack as either handles
+// or executing methods, so that it can't be deleted during class redefinition
+// and class unloading.
+class MetadataOnStackMark : public StackObj {
+ NOT_PRODUCT(static bool _is_active;)
+ public:
+ MetadataOnStackMark();
+ ~MetadataOnStackMark();
+ static void record(Metadata* m);
+};
+
#endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES_HPP