Mercurial > hg > truffle
comparison src/share/vm/prims/jvmtiRedefineClasses.hpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d1603768966 |
children | fb19af007ffc |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
208 // There is one small complication in copying the entries from old_cp | 208 // There is one small complication in copying the entries from old_cp |
209 // to merge_cp. Two of the CP entry types are special in that they are | 209 // to merge_cp. Two of the CP entry types are special in that they are |
210 // lazily resolved. Before explaining the copying complication, we need | 210 // lazily resolved. Before explaining the copying complication, we need |
211 // to digress into CP entry resolution. | 211 // to digress into CP entry resolution. |
212 // | 212 // |
213 // JVM_CONSTANT_Class and JVM_CONSTANT_String entries are present in | 213 // JVM_CONSTANT_Class entries are present in the class file, but are not |
214 // the class file, but are not stored in memory as such until they are | 214 // stored in memory as such until they are resolved. The entries are not |
215 // resolved. The entries are not resolved unless they are used because | 215 // resolved unless they are used because resolution is expensive. During class |
216 // resolution is expensive. During class file parsing the entries are | 216 // file parsing the entries are initially stored in memory as |
217 // initially stored in memory as JVM_CONSTANT_ClassIndex and | 217 // JVM_CONSTANT_ClassIndex and JVM_CONSTANT_StringIndex entries. These special |
218 // JVM_CONSTANT_StringIndex entries. These special CP entry types | 218 // CP entry types indicate that the JVM_CONSTANT_Class and JVM_CONSTANT_String |
219 // indicate that the JVM_CONSTANT_Class and JVM_CONSTANT_String entries | 219 // entries have been parsed, but the index values in the entries have not been |
220 // have been parsed, but the index values in the entries have not been | |
221 // validated. After the entire constant pool has been parsed, the index | 220 // validated. After the entire constant pool has been parsed, the index |
222 // values can be validated and then the entries are converted into | 221 // values can be validated and then the entries are converted into |
223 // JVM_CONSTANT_UnresolvedClass and JVM_CONSTANT_UnresolvedString | 222 // JVM_CONSTANT_UnresolvedClass and JVM_CONSTANT_String |
224 // entries. During this conversion process, the UTF8 values that are | 223 // entries. During this conversion process, the UTF8 values that are |
225 // indirectly referenced by the JVM_CONSTANT_ClassIndex and | 224 // indirectly referenced by the JVM_CONSTANT_ClassIndex and |
226 // JVM_CONSTANT_StringIndex entries are changed into Symbol*s and the | 225 // JVM_CONSTANT_StringIndex entries are changed into Symbol*s and the |
227 // entries are modified to refer to the Symbol*s. This optimization | 226 // entries are modified to refer to the Symbol*s. This optimization |
228 // eliminates one level of indirection for those two CP entry types and | 227 // eliminates one level of indirection for those two CP entry types and |
229 // gets the entries ready for verification. During class file parsing | 228 // gets the entries ready for verification. Verification expects to |
230 // it is also possible for JVM_CONSTANT_UnresolvedString entries to be | 229 // find JVM_CONSTANT_UnresolvedClass but not JVM_CONSTANT_Class entries. |
231 // resolved into JVM_CONSTANT_String entries. Verification expects to | |
232 // find JVM_CONSTANT_UnresolvedClass and either JVM_CONSTANT_String or | |
233 // JVM_CONSTANT_UnresolvedString entries and not JVM_CONSTANT_Class | |
234 // entries. | |
235 // | 230 // |
236 // Now we can get back to the copying complication. When we copy | 231 // Now we can get back to the copying complication. When we copy |
237 // entries from old_cp to merge_cp, we have to revert any | 232 // entries from old_cp to merge_cp, we have to revert any |
238 // JVM_CONSTANT_Class entries to JVM_CONSTANT_UnresolvedClass entries | 233 // JVM_CONSTANT_Class entries to JVM_CONSTANT_UnresolvedClass entries |
239 // or verification will fail. | 234 // or verification will fail. |
258 // the entry is simply copied from scratch_cp to the end of merge_cp. | 253 // the entry is simply copied from scratch_cp to the end of merge_cp. |
259 // If the index in scratch_cp is different than the destination index | 254 // If the index in scratch_cp is different than the destination index |
260 // in merge_cp, then the change in index value is tracked. | 255 // in merge_cp, then the change in index value is tracked. |
261 // | 256 // |
262 // Note: the above discussion for the direct CP entries also applies | 257 // Note: the above discussion for the direct CP entries also applies |
263 // to the JVM_CONSTANT_Unresolved{Class,String} entry types. | 258 // to the JVM_CONSTANT_UnresolvedClass entry types. |
264 // | 259 // |
265 // For the JVM_CONSTANT_{Class,String} entry types, since there is only | 260 // For the JVM_CONSTANT_Class entry types, since there is only |
266 // one data element at the end of the recursion, we know that we have | 261 // one data element at the end of the recursion, we know that we have |
267 // either one or two unique entries. If the JVM_CONSTANT_Utf8 entry is | 262 // either one or two unique entries. If the JVM_CONSTANT_Utf8 entry is |
268 // unique then it is appended to merge_cp before the current entry. | 263 // unique then it is appended to merge_cp before the current entry. |
269 // If the JVM_CONSTANT_Utf8 entry is not unique, then the current entry | 264 // If the JVM_CONSTANT_Utf8 entry is not unique, then the current entry |
270 // is updated to refer to the duplicate entry in merge_cp before it is | 265 // is updated to refer to the duplicate entry in merge_cp before it is |
271 // appended to merge_cp. Again, any changes in index values are tracked | 266 // appended to merge_cp. Again, any changes in index values are tracked |
272 // as needed. | 267 // as needed. |
273 // | 268 // |
274 // Note: the above discussion for JVM_CONSTANT_{Class,String} entry | 269 // Note: the above discussion for JVM_CONSTANT_Class entry |
275 // types is theoretical. Since those entry types have already been | 270 // types is theoretical. Since those entry types have already been |
276 // optimized into JVM_CONSTANT_Unresolved{Class,String} entry types, | 271 // optimized into JVM_CONSTANT_UnresolvedClass entry types, |
277 // they are handled as direct CP entries. | 272 // they are handled as direct CP entries. |
278 // | 273 // |
279 // For the JVM_CONSTANT_NameAndType entry type, since there are two | 274 // For the JVM_CONSTANT_NameAndType entry type, since there are two |
280 // data elements at the end of the recursions, we know that we have | 275 // data elements at the end of the recursions, we know that we have |
281 // between one and three unique entries. Any unique JVM_CONSTANT_Utf8 | 276 // between one and three unique entries. Any unique JVM_CONSTANT_Utf8 |
318 // (indirect) use of the Relocator class that the max instruction | 313 // (indirect) use of the Relocator class that the max instruction |
319 // size is 4 bytes. goto_w and jsr_w are 5 bytes and wide/iinc is | 314 // size is 4 bytes. goto_w and jsr_w are 5 bytes and wide/iinc is |
320 // 6 bytes. Perhaps Relocator only needs a 4 byte buffer to do | 315 // 6 bytes. Perhaps Relocator only needs a 4 byte buffer to do |
321 // what it does to the bytecodes. More investigation is needed. | 316 // what it does to the bytecodes. More investigation is needed. |
322 // | 317 // |
323 // - java.lang.Object methods can be called on arrays. This is | |
324 // implemented via the arrayKlassOop vtable which we don't | |
325 // update. For example, if we redefine java.lang.Object.toString(), | |
326 // then the new version of the method will not be called for array | |
327 // objects. | |
328 // | |
329 // - How do we know if redefine_single_class() and the guts of | 318 // - How do we know if redefine_single_class() and the guts of |
330 // instanceKlass are out of sync? I don't think this can be | 319 // InstanceKlass are out of sync? I don't think this can be |
331 // automated, but we should probably order the work in | 320 // automated, but we should probably order the work in |
332 // redefine_single_class() to match the order of field | 321 // redefine_single_class() to match the order of field |
333 // definitions in instanceKlass. We also need to add some | 322 // definitions in InstanceKlass. We also need to add some |
334 // comments about keeping things in sync. | 323 // comments about keeping things in sync. |
335 // | 324 // |
336 // - set_new_constant_pool() is huge and we should consider refactoring | 325 // - set_new_constant_pool() is huge and we should consider refactoring |
337 // it into smaller chunks of work. | 326 // it into smaller chunks of work. |
338 // | 327 // |
344 | 333 |
345 class VM_RedefineClasses: public VM_Operation { | 334 class VM_RedefineClasses: public VM_Operation { |
346 private: | 335 private: |
347 // These static fields are needed by SystemDictionary::classes_do() | 336 // These static fields are needed by SystemDictionary::classes_do() |
348 // facility and the adjust_cpool_cache_and_vtable() helper: | 337 // facility and the adjust_cpool_cache_and_vtable() helper: |
349 static objArrayOop _old_methods; | 338 static Array<Method*>* _old_methods; |
350 static objArrayOop _new_methods; | 339 static Array<Method*>* _new_methods; |
351 static methodOop* _matching_old_methods; | 340 static Method** _matching_old_methods; |
352 static methodOop* _matching_new_methods; | 341 static Method** _matching_new_methods; |
353 static methodOop* _deleted_methods; | 342 static Method** _deleted_methods; |
354 static methodOop* _added_methods; | 343 static Method** _added_methods; |
355 static int _matching_methods_length; | 344 static int _matching_methods_length; |
356 static int _deleted_methods_length; | 345 static int _deleted_methods_length; |
357 static int _added_methods_length; | 346 static int _added_methods_length; |
358 static klassOop _the_class_oop; | 347 static Klass* _the_class_oop; |
359 | 348 |
360 // The instance fields are used to pass information from | 349 // The instance fields are used to pass information from |
361 // doit_prologue() to doit() and doit_epilogue(). | 350 // doit_prologue() to doit() and doit_epilogue(). |
362 jint _class_count; | 351 jint _class_count; |
363 const jvmtiClassDefinition *_class_defs; // ptr to _class_count defs | 352 const jvmtiClassDefinition *_class_defs; // ptr to _class_count defs |
369 // _index_map_count is just an optimization for knowing if | 358 // _index_map_count is just an optimization for knowing if |
370 // _index_map_p contains any entries. | 359 // _index_map_p contains any entries. |
371 int _index_map_count; | 360 int _index_map_count; |
372 intArray * _index_map_p; | 361 intArray * _index_map_p; |
373 // ptr to _class_count scratch_classes | 362 // ptr to _class_count scratch_classes |
374 instanceKlassHandle * _scratch_classes; | 363 Klass** _scratch_classes; |
375 jvmtiError _res; | 364 jvmtiError _res; |
376 | 365 |
377 // Performance measurement support. These timers do not cover all | 366 // Performance measurement support. These timers do not cover all |
378 // the work done for JVM/TI RedefineClasses() but they do cover | 367 // the work done for JVM/TI RedefineClasses() but they do cover |
379 // the heavy lifting. | 368 // the heavy lifting. |
396 instanceKlassHandle the_class, instanceKlassHandle scratch_class); | 385 instanceKlassHandle the_class, instanceKlassHandle scratch_class); |
397 | 386 |
398 // Swap annotations[i] with annotations[j] | 387 // Swap annotations[i] with annotations[j] |
399 // Used by compare_and_normalize_class_versions() when normalizing | 388 // Used by compare_and_normalize_class_versions() when normalizing |
400 // overloaded methods or changing idnum as when adding or deleting methods. | 389 // overloaded methods or changing idnum as when adding or deleting methods. |
401 void swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class); | 390 void swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS); |
402 | 391 |
403 // Figure out which new methods match old methods in name and signature, | 392 // Figure out which new methods match old methods in name and signature, |
404 // which methods have been added, and which are no longer present | 393 // which methods have been added, and which are no longer present |
405 void compute_added_deleted_matching_methods(); | 394 void compute_added_deleted_matching_methods(); |
406 | 395 |
419 | 408 |
420 // Unevolving classes may point to methods of the_class directly | 409 // Unevolving classes may point to methods of the_class directly |
421 // from their constant pool caches, itables, and/or vtables. We | 410 // from their constant pool caches, itables, and/or vtables. We |
422 // use the SystemDictionary::classes_do() facility and this helper | 411 // use the SystemDictionary::classes_do() facility and this helper |
423 // to fix up these pointers. | 412 // to fix up these pointers. |
424 static void adjust_cpool_cache_and_vtable(klassOop k_oop, oop loader, TRAPS); | 413 static void adjust_cpool_cache_and_vtable(Klass* k_oop, ClassLoaderData* initiating_loader, TRAPS); |
414 static void adjust_array_vtable(Klass* k_oop); | |
425 | 415 |
426 // Install the redefinition of a class | 416 // Install the redefinition of a class |
427 void redefine_single_class(jclass the_jclass, | 417 void redefine_single_class(jclass the_jclass, |
428 instanceKlassHandle scratch_class, TRAPS); | 418 Klass* scratch_class_oop, TRAPS); |
429 | 419 |
430 // Increment the classRedefinedCount field in the specific instanceKlass | 420 // Increment the classRedefinedCount field in the specific InstanceKlass |
431 // and in all direct and indirect subclasses. | 421 // and in all direct and indirect subclasses. |
432 void increment_class_counter(instanceKlass *ik, TRAPS); | 422 void increment_class_counter(InstanceKlass *ik, TRAPS); |
433 | 423 |
434 // Support for constant pool merging (these routines are in alpha | 424 // Support for constant pool merging (these routines are in alpha |
435 // order): | 425 // order): |
436 void append_entry(constantPoolHandle scratch_cp, int scratch_i, | 426 void append_entry(constantPoolHandle scratch_cp, int scratch_i, |
437 constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS); | 427 constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS); |
438 int find_new_index(int old_index); | 428 int find_new_index(int old_index); |
439 bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1, | 429 bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1, |
440 constantPoolHandle cp2, int index2); | |
441 bool is_unresolved_string_mismatch(constantPoolHandle cp1, int index1, | |
442 constantPoolHandle cp2, int index2); | 430 constantPoolHandle cp2, int index2); |
443 void map_index(constantPoolHandle scratch_cp, int old_index, int new_index); | 431 void map_index(constantPoolHandle scratch_cp, int old_index, int new_index); |
444 bool merge_constant_pools(constantPoolHandle old_cp, | 432 bool merge_constant_pools(constantPoolHandle old_cp, |
445 constantPoolHandle scratch_cp, constantPoolHandle *merge_cp_p, | 433 constantPoolHandle scratch_cp, constantPoolHandle *merge_cp_p, |
446 int *merge_cp_length_p, TRAPS); | 434 int *merge_cp_length_p, TRAPS); |
447 jvmtiError merge_cp_and_rewrite(instanceKlassHandle the_class, | 435 jvmtiError merge_cp_and_rewrite(instanceKlassHandle the_class, |
448 instanceKlassHandle scratch_class, TRAPS); | 436 instanceKlassHandle scratch_class, TRAPS); |
449 u2 rewrite_cp_ref_in_annotation_data( | 437 u2 rewrite_cp_ref_in_annotation_data( |
450 typeArrayHandle annotations_typeArray, int &byte_i_ref, | 438 AnnotationArray* annotations_typeArray, int &byte_i_ref, |
451 const char * trace_mesg, TRAPS); | 439 const char * trace_mesg, TRAPS); |
452 bool rewrite_cp_refs(instanceKlassHandle scratch_class, TRAPS); | 440 bool rewrite_cp_refs(instanceKlassHandle scratch_class, TRAPS); |
453 bool rewrite_cp_refs_in_annotation_struct( | 441 bool rewrite_cp_refs_in_annotation_struct( |
454 typeArrayHandle class_annotations, int &byte_i_ref, TRAPS); | 442 AnnotationArray* class_annotations, int &byte_i_ref, TRAPS); |
455 bool rewrite_cp_refs_in_annotations_typeArray( | 443 bool rewrite_cp_refs_in_annotations_typeArray( |
456 typeArrayHandle annotations_typeArray, int &byte_i_ref, TRAPS); | 444 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS); |
457 bool rewrite_cp_refs_in_class_annotations( | 445 bool rewrite_cp_refs_in_class_annotations( |
458 instanceKlassHandle scratch_class, TRAPS); | 446 instanceKlassHandle scratch_class, TRAPS); |
459 bool rewrite_cp_refs_in_element_value( | 447 bool rewrite_cp_refs_in_element_value( |
460 typeArrayHandle class_annotations, int &byte_i_ref, TRAPS); | 448 AnnotationArray* class_annotations, int &byte_i_ref, TRAPS); |
461 bool rewrite_cp_refs_in_fields_annotations( | 449 bool rewrite_cp_refs_in_fields_annotations( |
462 instanceKlassHandle scratch_class, TRAPS); | 450 instanceKlassHandle scratch_class, TRAPS); |
463 void rewrite_cp_refs_in_method(methodHandle method, | 451 void rewrite_cp_refs_in_method(methodHandle method, |
464 methodHandle * new_method_p, TRAPS); | 452 methodHandle * new_method_p, TRAPS); |
465 bool rewrite_cp_refs_in_methods(instanceKlassHandle scratch_class, TRAPS); | 453 bool rewrite_cp_refs_in_methods(instanceKlassHandle scratch_class, TRAPS); |
471 instanceKlassHandle scratch_class, TRAPS); | 459 instanceKlassHandle scratch_class, TRAPS); |
472 void rewrite_cp_refs_in_stack_map_table(methodHandle method, TRAPS); | 460 void rewrite_cp_refs_in_stack_map_table(methodHandle method, TRAPS); |
473 void rewrite_cp_refs_in_verification_type_info( | 461 void rewrite_cp_refs_in_verification_type_info( |
474 address& stackmap_addr_ref, address stackmap_end, u2 frame_i, | 462 address& stackmap_addr_ref, address stackmap_end, u2 frame_i, |
475 u1 frame_size, TRAPS); | 463 u1 frame_size, TRAPS); |
476 void set_new_constant_pool(instanceKlassHandle scratch_class, | 464 void set_new_constant_pool(ClassLoaderData* loader_data, |
477 constantPoolHandle scratch_cp, int scratch_cp_length, bool shrink, TRAPS); | 465 instanceKlassHandle scratch_class, |
466 constantPoolHandle scratch_cp, int scratch_cp_length, TRAPS); | |
478 | 467 |
479 void flush_dependent_code(instanceKlassHandle k_h, TRAPS); | 468 void flush_dependent_code(instanceKlassHandle k_h, TRAPS); |
480 | 469 |
481 static void check_class(klassOop k_oop, oop initiating_loader, TRAPS) PRODUCT_RETURN; | 470 static void check_class(Klass* k_oop, ClassLoaderData* initiating_loader, TRAPS) PRODUCT_RETURN; |
482 | 471 |
483 static void dump_methods() PRODUCT_RETURN; | 472 static void dump_methods() PRODUCT_RETURN; |
484 | 473 |
485 public: | 474 public: |
486 VM_RedefineClasses(jint class_count, | 475 VM_RedefineClasses(jint class_count, |
497 // Modifiable test must be shared between IsModifiableClass query | 486 // Modifiable test must be shared between IsModifiableClass query |
498 // and redefine implementation | 487 // and redefine implementation |
499 static bool is_modifiable_class(oop klass_mirror); | 488 static bool is_modifiable_class(oop klass_mirror); |
500 }; | 489 }; |
501 | 490 |
491 | |
492 // Helper class to mark and unmark metadata used on the stack as either handles | |
493 // or executing methods, so that it can't be deleted during class redefinition | |
494 // and class unloading. | |
495 class MetadataOnStackMark : public StackObj { | |
496 NOT_PRODUCT(static bool _is_active;) | |
497 public: | |
498 MetadataOnStackMark(); | |
499 ~MetadataOnStackMark(); | |
500 static void record(Metadata* m); | |
501 }; | |
502 | |
502 #endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES_HPP | 503 #endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES_HPP |