Mercurial > hg > truffle
comparison src/share/vm/classfile/javaClasses.cpp @ 3938:e6b1331a51d2
7086585: make Java field injection more flexible
Reviewed-by: jrose, twisti, kvn, coleenp
author | never |
---|---|
date | Sat, 10 Sep 2011 17:29:02 -0700 |
parents | b0efc7ee3b31 |
children | 8ed53447f690 |
comparison
equal
deleted
inserted
replaced
3937:c565834fb592 | 3938:e6b1331a51d2 |
---|---|
31 #include "compiler/compilerOracle.hpp" | 31 #include "compiler/compilerOracle.hpp" |
32 #include "interpreter/interpreter.hpp" | 32 #include "interpreter/interpreter.hpp" |
33 #include "memory/oopFactory.hpp" | 33 #include "memory/oopFactory.hpp" |
34 #include "memory/resourceArea.hpp" | 34 #include "memory/resourceArea.hpp" |
35 #include "memory/universe.inline.hpp" | 35 #include "memory/universe.inline.hpp" |
36 #include "oops/fieldStreams.hpp" | |
36 #include "oops/instanceKlass.hpp" | 37 #include "oops/instanceKlass.hpp" |
37 #include "oops/instanceMirrorKlass.hpp" | 38 #include "oops/instanceMirrorKlass.hpp" |
38 #include "oops/klass.hpp" | 39 #include "oops/klass.hpp" |
39 #include "oops/klassOop.hpp" | 40 #include "oops/klassOop.hpp" |
40 #include "oops/methodOop.hpp" | 41 #include "oops/methodOop.hpp" |
55 # include "thread_solaris.inline.hpp" | 56 # include "thread_solaris.inline.hpp" |
56 #endif | 57 #endif |
57 #ifdef TARGET_OS_FAMILY_windows | 58 #ifdef TARGET_OS_FAMILY_windows |
58 # include "thread_windows.inline.hpp" | 59 # include "thread_windows.inline.hpp" |
59 #endif | 60 #endif |
61 | |
62 #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \ | |
63 klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum); | |
64 | |
65 #define DECLARE_INJECTED_FIELD(klass, name, signature, may_be_java) \ | |
66 { SystemDictionary::WK_KLASS_ENUM_NAME(klass), vmSymbols::VM_SYMBOL_ENUM_NAME(name##_name), vmSymbols::VM_SYMBOL_ENUM_NAME(signature), may_be_java }, | |
67 | |
68 InjectedField JavaClasses::_injected_fields[] = { | |
69 ALL_INJECTED_FIELDS(DECLARE_INJECTED_FIELD) | |
70 }; | |
71 | |
72 int JavaClasses::compute_injected_offset(InjectedFieldID id) { | |
73 return _injected_fields[id].compute_offset(); | |
74 } | |
75 | |
76 | |
77 InjectedField* JavaClasses::get_injected(Symbol* class_name, int* field_count) { | |
78 *field_count = 0; | |
79 | |
80 vmSymbols::SID sid = vmSymbols::find_sid(class_name); | |
81 if (sid == vmSymbols::NO_SID) { | |
82 // Only well known classes can inject fields | |
83 return NULL; | |
84 } | |
85 | |
86 int count = 0; | |
87 int start = -1; | |
88 | |
89 #define LOOKUP_INJECTED_FIELD(klass, name, signature, may_be_java) \ | |
90 if (sid == vmSymbols::VM_SYMBOL_ENUM_NAME(klass)) { \ | |
91 count++; \ | |
92 if (start == -1) start = klass##_##name##_enum; \ | |
93 } | |
94 ALL_INJECTED_FIELDS(LOOKUP_INJECTED_FIELD); | |
95 #undef LOOKUP_INJECTED_FIELD | |
96 | |
97 if (start != -1) { | |
98 *field_count = count; | |
99 return _injected_fields + start; | |
100 } | |
101 return NULL; | |
102 } | |
103 | |
60 | 104 |
61 static bool find_field(instanceKlass* ik, | 105 static bool find_field(instanceKlass* ik, |
62 Symbol* name_symbol, Symbol* signature_symbol, | 106 Symbol* name_symbol, Symbol* signature_symbol, |
63 fieldDescriptor* fd, | 107 fieldDescriptor* fd, |
64 bool allow_super = false) { | 108 bool allow_super = false) { |
426 } | 470 } |
427 } | 471 } |
428 } | 472 } |
429 | 473 |
430 | 474 |
431 // During bootstrap, java.lang.Class wasn't loaded so static field | |
432 // offsets were computed without the size added it. Go back and | |
433 // update all the static field offsets to included the size. | |
434 static void fixup_static_field(fieldDescriptor* fd, TRAPS) { | |
435 if (fd->is_static()) { | |
436 int real_offset = fd->offset() + instanceMirrorKlass::offset_of_static_fields(); | |
437 typeArrayOop fields = instanceKlass::cast(fd->field_holder())->fields(); | |
438 fields->short_at_put(fd->index() + instanceKlass::low_offset, extract_low_short_from_int(real_offset)); | |
439 fields->short_at_put(fd->index() + instanceKlass::high_offset, extract_high_short_from_int(real_offset)); | |
440 } | |
441 } | |
442 | |
443 void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) { | 475 void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) { |
444 assert(instanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already"); | 476 assert(instanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already"); |
445 | 477 |
446 if (k->oop_is_instance()) { | 478 if (k->oop_is_instance()) { |
447 // Fixup the offsets | 479 // During bootstrap, java.lang.Class wasn't loaded so static field |
448 instanceKlass::cast(k())->do_local_static_fields(&fixup_static_field, CHECK); | 480 // offsets were computed without the size added it. Go back and |
481 // update all the static field offsets to included the size. | |
482 for (JavaFieldStream fs(instanceKlass::cast(k())); !fs.done(); fs.next()) { | |
483 if (fs.access_flags().is_static()) { | |
484 int real_offset = fs.offset() + instanceMirrorKlass::offset_of_static_fields(); | |
485 fs.set_offset(real_offset); | |
486 } | |
487 } | |
449 } | 488 } |
450 create_mirror(k, CHECK); | 489 create_mirror(k, CHECK); |
451 } | 490 } |
452 | 491 |
453 oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) { | 492 oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) { |
460 k->set_modifier_flags(computed_modifiers); | 499 k->set_modifier_flags(computed_modifiers); |
461 if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) { | 500 if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) { |
462 // Allocate mirror (java.lang.Class instance) | 501 // Allocate mirror (java.lang.Class instance) |
463 Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0); | 502 Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0); |
464 // Setup indirections | 503 // Setup indirections |
465 mirror->obj_field_put(klass_offset, k()); | 504 mirror->obj_field_put(_klass_offset, k()); |
466 k->set_java_mirror(mirror()); | 505 k->set_java_mirror(mirror()); |
467 | 506 |
468 instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass()); | 507 instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass()); |
469 java_lang_Class::set_oop_size(mirror(), mk->instance_size(k)); | 508 java_lang_Class::set_oop_size(mirror(), mk->instance_size(k)); |
470 java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); | 509 java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); |
502 } | 541 } |
503 | 542 |
504 | 543 |
505 | 544 |
506 int java_lang_Class::oop_size(oop java_class) { | 545 int java_lang_Class::oop_size(oop java_class) { |
507 assert(oop_size_offset != 0, "must be set"); | 546 assert(_oop_size_offset != 0, "must be set"); |
508 return java_class->int_field(oop_size_offset); | 547 return java_class->int_field(_oop_size_offset); |
509 } | 548 } |
510 void java_lang_Class::set_oop_size(oop java_class, int size) { | 549 void java_lang_Class::set_oop_size(oop java_class, int size) { |
511 assert(oop_size_offset != 0, "must be set"); | 550 assert(_oop_size_offset != 0, "must be set"); |
512 java_class->int_field_put(oop_size_offset, size); | 551 java_class->int_field_put(_oop_size_offset, size); |
513 } | 552 } |
514 int java_lang_Class::static_oop_field_count(oop java_class) { | 553 int java_lang_Class::static_oop_field_count(oop java_class) { |
515 assert(static_oop_field_count_offset != 0, "must be set"); | 554 assert(_static_oop_field_count_offset != 0, "must be set"); |
516 return java_class->int_field(static_oop_field_count_offset); | 555 return java_class->int_field(_static_oop_field_count_offset); |
517 } | 556 } |
518 void java_lang_Class::set_static_oop_field_count(oop java_class, int size) { | 557 void java_lang_Class::set_static_oop_field_count(oop java_class, int size) { |
519 assert(static_oop_field_count_offset != 0, "must be set"); | 558 assert(_static_oop_field_count_offset != 0, "must be set"); |
520 java_class->int_field_put(static_oop_field_count_offset, size); | 559 java_class->int_field_put(_static_oop_field_count_offset, size); |
521 } | 560 } |
522 | |
523 | |
524 | |
525 | 561 |
526 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { | 562 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { |
527 // This should be improved by adding a field at the Java level or by | 563 // This should be improved by adding a field at the Java level or by |
528 // introducing a new VM klass (see comment in ClassFileParser) | 564 // introducing a new VM klass (see comment in ClassFileParser) |
529 oop java_class = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance((oop)NULL, CHECK_0); | 565 oop java_class = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance((oop)NULL, CHECK_0); |
540 | 576 |
541 | 577 |
542 klassOop java_lang_Class::as_klassOop(oop java_class) { | 578 klassOop java_lang_Class::as_klassOop(oop java_class) { |
543 //%note memory_2 | 579 //%note memory_2 |
544 assert(java_lang_Class::is_instance(java_class), "must be a Class object"); | 580 assert(java_lang_Class::is_instance(java_class), "must be a Class object"); |
545 klassOop k = klassOop(java_class->obj_field(klass_offset)); | 581 klassOop k = klassOop(java_class->obj_field(_klass_offset)); |
546 assert(k == NULL || k->is_klass(), "type check"); | 582 assert(k == NULL || k->is_klass(), "type check"); |
547 return k; | 583 return k; |
548 } | 584 } |
549 | 585 |
550 | 586 |
596 return name; | 632 return name; |
597 } | 633 } |
598 | 634 |
599 | 635 |
600 klassOop java_lang_Class::array_klass(oop java_class) { | 636 klassOop java_lang_Class::array_klass(oop java_class) { |
601 klassOop k = klassOop(java_class->obj_field(array_klass_offset)); | 637 klassOop k = klassOop(java_class->obj_field(_array_klass_offset)); |
602 assert(k == NULL || k->is_klass() && Klass::cast(k)->oop_is_javaArray(), "should be array klass"); | 638 assert(k == NULL || k->is_klass() && Klass::cast(k)->oop_is_javaArray(), "should be array klass"); |
603 return k; | 639 return k; |
604 } | 640 } |
605 | 641 |
606 | 642 |
607 void java_lang_Class::set_array_klass(oop java_class, klassOop klass) { | 643 void java_lang_Class::set_array_klass(oop java_class, klassOop klass) { |
608 assert(klass->is_klass() && Klass::cast(klass)->oop_is_javaArray(), "should be array klass"); | 644 assert(klass->is_klass() && Klass::cast(klass)->oop_is_javaArray(), "should be array klass"); |
609 java_class->obj_field_put(array_klass_offset, klass); | 645 java_class->obj_field_put(_array_klass_offset, klass); |
610 } | 646 } |
611 | 647 |
612 | 648 |
613 methodOop java_lang_Class::resolved_constructor(oop java_class) { | 649 methodOop java_lang_Class::resolved_constructor(oop java_class) { |
614 oop constructor = java_class->obj_field(resolved_constructor_offset); | 650 oop constructor = java_class->obj_field(_resolved_constructor_offset); |
615 assert(constructor == NULL || constructor->is_method(), "should be method"); | 651 assert(constructor == NULL || constructor->is_method(), "should be method"); |
616 return methodOop(constructor); | 652 return methodOop(constructor); |
617 } | 653 } |
618 | 654 |
619 | 655 |
620 void java_lang_Class::set_resolved_constructor(oop java_class, methodOop constructor) { | 656 void java_lang_Class::set_resolved_constructor(oop java_class, methodOop constructor) { |
621 assert(constructor->is_method(), "should be method"); | 657 assert(constructor->is_method(), "should be method"); |
622 java_class->obj_field_put(resolved_constructor_offset, constructor); | 658 java_class->obj_field_put(_resolved_constructor_offset, constructor); |
623 } | 659 } |
624 | 660 |
625 | 661 |
626 bool java_lang_Class::is_primitive(oop java_class) { | 662 bool java_lang_Class::is_primitive(oop java_class) { |
627 // should assert: | 663 // should assert: |
628 //assert(java_lang_Class::is_instance(java_class), "must be a Class object"); | 664 //assert(java_lang_Class::is_instance(java_class), "must be a Class object"); |
629 klassOop k = klassOop(java_class->obj_field(klass_offset)); | 665 klassOop k = klassOop(java_class->obj_field(_klass_offset)); |
630 return k == NULL; | 666 return k == NULL; |
631 } | 667 } |
632 | 668 |
633 | 669 |
634 BasicType java_lang_Class::primitive_type(oop java_class) { | 670 BasicType java_lang_Class::primitive_type(oop java_class) { |
635 assert(java_lang_Class::is_primitive(java_class), "just checking"); | 671 assert(java_lang_Class::is_primitive(java_class), "just checking"); |
636 klassOop ak = klassOop(java_class->obj_field(array_klass_offset)); | 672 klassOop ak = klassOop(java_class->obj_field(_array_klass_offset)); |
637 BasicType type = T_VOID; | 673 BasicType type = T_VOID; |
638 if (ak != NULL) { | 674 if (ak != NULL) { |
639 // Note: create_basic_type_mirror above initializes ak to a non-null value. | 675 // Note: create_basic_type_mirror above initializes ak to a non-null value. |
640 type = arrayKlass::cast(ak)->element_type(); | 676 type = arrayKlass::cast(ak)->element_type(); |
641 } else { | 677 } else { |
666 return mirror; | 702 return mirror; |
667 } | 703 } |
668 | 704 |
669 bool java_lang_Class::offsets_computed = false; | 705 bool java_lang_Class::offsets_computed = false; |
670 int java_lang_Class::classRedefinedCount_offset = -1; | 706 int java_lang_Class::classRedefinedCount_offset = -1; |
671 int java_lang_Class::parallelCapable_offset = -1; | |
672 | 707 |
673 void java_lang_Class::compute_offsets() { | 708 void java_lang_Class::compute_offsets() { |
674 assert(!offsets_computed, "offsets should be initialized only once"); | 709 assert(!offsets_computed, "offsets should be initialized only once"); |
675 offsets_computed = true; | 710 offsets_computed = true; |
676 | 711 |
677 klassOop k = SystemDictionary::Class_klass(); | 712 klassOop klass_oop = SystemDictionary::Class_klass(); |
678 // The classRedefinedCount field is only present starting in 1.5, | 713 // The classRedefinedCount field is only present starting in 1.5, |
679 // so don't go fatal. | 714 // so don't go fatal. |
680 compute_optional_offset(classRedefinedCount_offset, | 715 compute_optional_offset(classRedefinedCount_offset, |
681 k, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature()); | 716 klass_oop, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature()); |
682 | 717 |
683 // The field indicating parallelCapable (parallelLockMap) is only present starting in 7, | 718 CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); |
684 klassOop k1 = SystemDictionary::ClassLoader_klass(); | |
685 compute_optional_offset(parallelCapable_offset, | |
686 k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature()); | |
687 } | |
688 | |
689 // For class loader classes, parallelCapable defined | |
690 // based on non-null field | |
691 // Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it | |
692 bool java_lang_Class::parallelCapable(oop class_loader) { | |
693 if (!JDK_Version::is_gte_jdk17x_version() | |
694 || parallelCapable_offset == -1) { | |
695 // Default for backward compatibility is false | |
696 return false; | |
697 } | |
698 return (class_loader->obj_field(parallelCapable_offset) != NULL); | |
699 } | 719 } |
700 | 720 |
701 int java_lang_Class::classRedefinedCount(oop the_class_mirror) { | 721 int java_lang_Class::classRedefinedCount(oop the_class_mirror) { |
702 if (!JDK_Version::is_gte_jdk15x_version() | 722 if (!JDK_Version::is_gte_jdk15x_version() |
703 || classRedefinedCount_offset == -1) { | 723 || classRedefinedCount_offset == -1) { |
2306 // Support for java_lang_invoke_MethodHandle | 2326 // Support for java_lang_invoke_MethodHandle |
2307 | 2327 |
2308 int java_lang_invoke_MethodHandle::_type_offset; | 2328 int java_lang_invoke_MethodHandle::_type_offset; |
2309 int java_lang_invoke_MethodHandle::_vmtarget_offset; | 2329 int java_lang_invoke_MethodHandle::_vmtarget_offset; |
2310 int java_lang_invoke_MethodHandle::_vmentry_offset; | 2330 int java_lang_invoke_MethodHandle::_vmentry_offset; |
2311 int java_lang_invoke_MethodHandle::_vmslots_offset; | |
2312 | 2331 |
2313 int java_lang_invoke_MemberName::_clazz_offset; | 2332 int java_lang_invoke_MemberName::_clazz_offset; |
2314 int java_lang_invoke_MemberName::_name_offset; | 2333 int java_lang_invoke_MemberName::_name_offset; |
2315 int java_lang_invoke_MemberName::_type_offset; | 2334 int java_lang_invoke_MemberName::_type_offset; |
2316 int java_lang_invoke_MemberName::_flags_offset; | 2335 int java_lang_invoke_MemberName::_flags_offset; |
2325 int java_lang_invoke_AdapterMethodHandle::_conversion_offset; | 2344 int java_lang_invoke_AdapterMethodHandle::_conversion_offset; |
2326 | 2345 |
2327 int java_lang_invoke_CountingMethodHandle::_vmcount_offset; | 2346 int java_lang_invoke_CountingMethodHandle::_vmcount_offset; |
2328 | 2347 |
2329 void java_lang_invoke_MethodHandle::compute_offsets() { | 2348 void java_lang_invoke_MethodHandle::compute_offsets() { |
2330 klassOop k = SystemDictionary::MethodHandle_klass(); | 2349 klassOop klass_oop = SystemDictionary::MethodHandle_klass(); |
2331 if (k != NULL && EnableInvokeDynamic) { | 2350 if (klass_oop != NULL && EnableInvokeDynamic) { |
2332 bool allow_super = false; | 2351 bool allow_super = false; |
2333 compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature(), allow_super); | 2352 compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature(), allow_super); |
2334 compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature(), allow_super); | 2353 METHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); |
2335 compute_offset(_vmentry_offset, k, vmSymbols::vmentry_name(), vmSymbols::machine_word_signature(), allow_super); | |
2336 | |
2337 // Note: MH.vmslots (if it is present) is a hoisted copy of MH.type.form.vmslots. | |
2338 // It is optional pending experiments to keep or toss. | |
2339 compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), allow_super); | |
2340 } | 2354 } |
2341 } | 2355 } |
2342 | 2356 |
2343 void java_lang_invoke_MemberName::compute_offsets() { | 2357 void java_lang_invoke_MemberName::compute_offsets() { |
2344 klassOop k = SystemDictionary::MemberName_klass(); | 2358 klassOop klass_oop = SystemDictionary::MemberName_klass(); |
2345 if (k != NULL && EnableInvokeDynamic) { | 2359 if (klass_oop != NULL && EnableInvokeDynamic) { |
2346 compute_offset(_clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); | 2360 compute_offset(_clazz_offset, klass_oop, vmSymbols::clazz_name(), vmSymbols::class_signature()); |
2347 compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); | 2361 compute_offset(_name_offset, klass_oop, vmSymbols::name_name(), vmSymbols::string_signature()); |
2348 compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::object_signature()); | 2362 compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::object_signature()); |
2349 compute_offset(_flags_offset, k, vmSymbols::flags_name(), vmSymbols::int_signature()); | 2363 compute_offset(_flags_offset, klass_oop, vmSymbols::flags_name(), vmSymbols::int_signature()); |
2350 compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature()); | 2364 compute_offset(_vmindex_offset, klass_oop, vmSymbols::vmindex_name(), vmSymbols::int_signature()); |
2351 compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature()); | 2365 MEMBERNAME_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); |
2352 } | 2366 } |
2353 } | 2367 } |
2354 | 2368 |
2355 void java_lang_invoke_DirectMethodHandle::compute_offsets() { | 2369 void java_lang_invoke_DirectMethodHandle::compute_offsets() { |
2356 klassOop k = SystemDictionary::DirectMethodHandle_klass(); | 2370 klassOop k = SystemDictionary::DirectMethodHandle_klass(); |
2357 if (k != NULL && EnableInvokeDynamic) { | 2371 if (k != NULL && EnableInvokeDynamic) { |
2358 compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature(), true); | 2372 DIRECTMETHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); |
2359 } | 2373 } |
2360 } | 2374 } |
2361 | 2375 |
2362 void java_lang_invoke_BoundMethodHandle::compute_offsets() { | 2376 void java_lang_invoke_BoundMethodHandle::compute_offsets() { |
2363 klassOop k = SystemDictionary::BoundMethodHandle_klass(); | 2377 klassOop k = SystemDictionary::BoundMethodHandle_klass(); |
2397 | 2411 |
2398 void java_lang_invoke_MethodHandle::set_type(oop mh, oop mtype) { | 2412 void java_lang_invoke_MethodHandle::set_type(oop mh, oop mtype) { |
2399 mh->obj_field_put(_type_offset, mtype); | 2413 mh->obj_field_put(_type_offset, mtype); |
2400 } | 2414 } |
2401 | 2415 |
2402 int java_lang_invoke_MethodHandle::vmslots(oop mh) { | |
2403 int vmslots_offset = _vmslots_offset; | |
2404 if (vmslots_offset != 0) { | |
2405 #ifdef ASSERT | |
2406 int x = mh->int_field(vmslots_offset); | |
2407 int y = compute_vmslots(mh); | |
2408 assert(x == y, "correct hoisted value"); | |
2409 #endif | |
2410 return mh->int_field(vmslots_offset); | |
2411 } else { | |
2412 return compute_vmslots(mh); | |
2413 } | |
2414 } | |
2415 | |
2416 // if MH.vmslots exists, hoist into it the value of type.form.vmslots | |
2417 void java_lang_invoke_MethodHandle::init_vmslots(oop mh) { | |
2418 int vmslots_offset = _vmslots_offset; | |
2419 if (vmslots_offset != 0) { | |
2420 mh->int_field_put(vmslots_offset, compute_vmslots(mh)); | |
2421 } | |
2422 } | |
2423 | |
2424 // fetch type.form.vmslots, which is the number of JVM stack slots | 2416 // fetch type.form.vmslots, which is the number of JVM stack slots |
2425 // required to carry the arguments of this MH | 2417 // required to carry the arguments of this MH |
2426 int java_lang_invoke_MethodHandle::compute_vmslots(oop mh) { | 2418 int java_lang_invoke_MethodHandle::vmslots(oop mh) { |
2427 oop mtype = type(mh); | 2419 oop mtype = type(mh); |
2428 if (mtype == NULL) return 0; // Java code would get NPE | 2420 if (mtype == NULL) return 0; // Java code would get NPE |
2429 oop form = java_lang_invoke_MethodType::form(mtype); | 2421 oop form = java_lang_invoke_MethodType::form(mtype); |
2430 if (form == NULL) return 0; // Java code would get NPE | 2422 if (form == NULL) return 0; // Java code would get NPE |
2431 return java_lang_invoke_MethodTypeForm::vmslots(form); | 2423 return java_lang_invoke_MethodTypeForm::vmslots(form); |
2641 compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), true); | 2633 compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), true); |
2642 compute_optional_offset(_vmlayout_offset, k, vmSymbols::vmlayout_name(), vmSymbols::object_signature()); | 2634 compute_optional_offset(_vmlayout_offset, k, vmSymbols::vmlayout_name(), vmSymbols::object_signature()); |
2643 compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_lang_invoke_MethodType_signature(), true); | 2635 compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_lang_invoke_MethodType_signature(), true); |
2644 compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_lang_invoke_MethodHandle_signature(), true); | 2636 compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_lang_invoke_MethodHandle_signature(), true); |
2645 if (_genericInvoker_offset == 0) _genericInvoker_offset = -1; // set to explicit "empty" value | 2637 if (_genericInvoker_offset == 0) _genericInvoker_offset = -1; // set to explicit "empty" value |
2638 METHODTYPEFORM_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); | |
2646 } | 2639 } |
2647 } | 2640 } |
2648 | 2641 |
2649 int java_lang_invoke_MethodTypeForm::vmslots(oop mtform) { | 2642 int java_lang_invoke_MethodTypeForm::vmslots(oop mtform) { |
2650 assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only"); | 2643 assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only"); |
2749 return result; | 2742 return result; |
2750 } | 2743 } |
2751 | 2744 |
2752 | 2745 |
2753 // Support for java_lang_ClassLoader | 2746 // Support for java_lang_ClassLoader |
2747 bool java_lang_ClassLoader::offsets_computed = false; | |
2748 int java_lang_ClassLoader::parallelCapable_offset = -1; | |
2749 | |
2750 void java_lang_ClassLoader::compute_offsets() { | |
2751 assert(!offsets_computed, "offsets should be initialized only once"); | |
2752 offsets_computed = true; | |
2753 | |
2754 // The field indicating parallelCapable (parallelLockMap) is only present starting in 7, | |
2755 klassOop k1 = SystemDictionary::ClassLoader_klass(); | |
2756 compute_optional_offset(parallelCapable_offset, | |
2757 k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature()); | |
2758 } | |
2754 | 2759 |
2755 oop java_lang_ClassLoader::parent(oop loader) { | 2760 oop java_lang_ClassLoader::parent(oop loader) { |
2756 assert(loader->is_oop(), "loader must be oop"); | 2761 assert(loader->is_oop(), "loader must be oop"); |
2757 return loader->obj_field(parent_offset); | 2762 return loader->obj_field(parent_offset); |
2758 } | 2763 } |
2759 | 2764 |
2765 | |
2766 // For class loader classes, parallelCapable defined | |
2767 // based on non-null field | |
2768 // Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it | |
2769 bool java_lang_ClassLoader::parallelCapable(oop class_loader) { | |
2770 if (!JDK_Version::is_gte_jdk17x_version() | |
2771 || parallelCapable_offset == -1) { | |
2772 // Default for backward compatibility is false | |
2773 return false; | |
2774 } | |
2775 return (class_loader->obj_field(parallelCapable_offset) != NULL); | |
2776 } | |
2760 | 2777 |
2761 bool java_lang_ClassLoader::is_trusted_loader(oop loader) { | 2778 bool java_lang_ClassLoader::is_trusted_loader(oop loader) { |
2762 // Fix for 4474172; see evaluation for more details | 2779 // Fix for 4474172; see evaluation for more details |
2763 loader = non_reflection_class_loader(loader); | 2780 loader = non_reflection_class_loader(loader); |
2764 | 2781 |
2805 | 2822 |
2806 int java_lang_String::value_offset; | 2823 int java_lang_String::value_offset; |
2807 int java_lang_String::offset_offset; | 2824 int java_lang_String::offset_offset; |
2808 int java_lang_String::count_offset; | 2825 int java_lang_String::count_offset; |
2809 int java_lang_String::hash_offset; | 2826 int java_lang_String::hash_offset; |
2810 int java_lang_Class::klass_offset; | 2827 int java_lang_Class::_klass_offset; |
2811 int java_lang_Class::array_klass_offset; | 2828 int java_lang_Class::_array_klass_offset; |
2812 int java_lang_Class::resolved_constructor_offset; | 2829 int java_lang_Class::_resolved_constructor_offset; |
2813 int java_lang_Class::number_of_fake_oop_fields; | 2830 int java_lang_Class::_oop_size_offset; |
2814 int java_lang_Class::oop_size_offset; | 2831 int java_lang_Class::_static_oop_field_count_offset; |
2815 int java_lang_Class::static_oop_field_count_offset; | |
2816 int java_lang_Throwable::backtrace_offset; | 2832 int java_lang_Throwable::backtrace_offset; |
2817 int java_lang_Throwable::detailMessage_offset; | 2833 int java_lang_Throwable::detailMessage_offset; |
2818 int java_lang_Throwable::cause_offset; | 2834 int java_lang_Throwable::cause_offset; |
2819 int java_lang_Throwable::stackTrace_offset; | 2835 int java_lang_Throwable::stackTrace_offset; |
2820 int java_lang_Throwable::static_unassigned_stacktrace_offset; | 2836 int java_lang_Throwable::static_unassigned_stacktrace_offset; |
2923 return _limit_offset; | 2939 return _limit_offset; |
2924 } | 2940 } |
2925 | 2941 |
2926 | 2942 |
2927 void java_nio_Buffer::compute_offsets() { | 2943 void java_nio_Buffer::compute_offsets() { |
2928 klassOop k = SystemDictionary::java_nio_Buffer_klass(); | 2944 klassOop k = SystemDictionary::nio_Buffer_klass(); |
2929 assert(k != NULL, "must be loaded in 1.4+"); | 2945 assert(k != NULL, "must be loaded in 1.4+"); |
2930 compute_offset(_limit_offset, k, vmSymbols::limit_name(), vmSymbols::int_signature()); | 2946 compute_offset(_limit_offset, k, vmSymbols::limit_name(), vmSymbols::int_signature()); |
2931 } | 2947 } |
2932 | 2948 |
2933 // Support for intrinsification of sun.misc.AtomicLongCSImpl.attemptUpdate | 2949 // Support for intrinsification of sun.misc.AtomicLongCSImpl.attemptUpdate |
2934 int sun_misc_AtomicLongCSImpl::value_offset() { | 2950 int sun_misc_AtomicLongCSImpl::value_offset() { |
2935 assert(SystemDictionary::sun_misc_AtomicLongCSImpl_klass() != NULL, "can't call this"); | 2951 assert(SystemDictionary::AtomicLongCSImpl_klass() != NULL, "can't call this"); |
2936 return _value_offset; | 2952 return _value_offset; |
2937 } | 2953 } |
2938 | 2954 |
2939 | 2955 |
2940 void sun_misc_AtomicLongCSImpl::compute_offsets() { | 2956 void sun_misc_AtomicLongCSImpl::compute_offsets() { |
2941 klassOop k = SystemDictionary::sun_misc_AtomicLongCSImpl_klass(); | 2957 klassOop k = SystemDictionary::AtomicLongCSImpl_klass(); |
2942 // If this class is not present, its value field offset won't be referenced. | 2958 // If this class is not present, its value field offset won't be referenced. |
2943 if (k != NULL) { | 2959 if (k != NULL) { |
2944 compute_offset(_value_offset, k, vmSymbols::value_name(), vmSymbols::long_signature()); | 2960 compute_offset(_value_offset, k, vmSymbols::value_name(), vmSymbols::long_signature()); |
2945 } | 2961 } |
2946 } | 2962 } |
2970 // Do the String Class | 2986 // Do the String Class |
2971 java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header; | 2987 java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header; |
2972 java_lang_String::offset_offset = java_lang_String::hc_offset_offset * x + header; | 2988 java_lang_String::offset_offset = java_lang_String::hc_offset_offset * x + header; |
2973 java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint); | 2989 java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint); |
2974 java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint); | 2990 java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint); |
2975 | |
2976 { | |
2977 // Do the Class Class | |
2978 int offset = header; | |
2979 java_lang_Class::oop_size_offset = header; | |
2980 offset += BytesPerInt; | |
2981 java_lang_Class::static_oop_field_count_offset = offset; | |
2982 offset = align_size_up(offset + BytesPerInt, x); | |
2983 java_lang_Class::klass_offset = offset; | |
2984 offset += x; | |
2985 java_lang_Class::array_klass_offset = offset; | |
2986 offset += x; | |
2987 java_lang_Class::resolved_constructor_offset = offset; | |
2988 } | |
2989 | |
2990 // This is NOT an offset | |
2991 java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields; | |
2992 | 2991 |
2993 // Throwable Class | 2992 // Throwable Class |
2994 java_lang_Throwable::backtrace_offset = java_lang_Throwable::hc_backtrace_offset * x + header; | 2993 java_lang_Throwable::backtrace_offset = java_lang_Throwable::hc_backtrace_offset * x + header; |
2995 java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header; | 2994 java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header; |
2996 java_lang_Throwable::cause_offset = java_lang_Throwable::hc_cause_offset * x + header; | 2995 java_lang_Throwable::cause_offset = java_lang_Throwable::hc_cause_offset * x + header; |
3039 } | 3038 } |
3040 | 3039 |
3041 | 3040 |
3042 // Compute non-hard-coded field offsets of all the classes in this file | 3041 // Compute non-hard-coded field offsets of all the classes in this file |
3043 void JavaClasses::compute_offsets() { | 3042 void JavaClasses::compute_offsets() { |
3044 | 3043 // java_lang_Class::compute_offsets was called earlier in bootstrap |
3045 java_lang_Class::compute_offsets(); | 3044 java_lang_ClassLoader::compute_offsets(); |
3046 java_lang_Thread::compute_offsets(); | 3045 java_lang_Thread::compute_offsets(); |
3047 java_lang_ThreadGroup::compute_offsets(); | 3046 java_lang_ThreadGroup::compute_offsets(); |
3048 if (EnableInvokeDynamic) { | 3047 if (EnableInvokeDynamic) { |
3049 java_lang_invoke_MethodHandle::compute_offsets(); | 3048 java_lang_invoke_MethodHandle::compute_offsets(); |
3050 java_lang_invoke_MemberName::compute_offsets(); | 3049 java_lang_invoke_MemberName::compute_offsets(); |
3265 if (!valid) vm_exit_during_initialization("Hard-coded field offset verification failed"); | 3264 if (!valid) vm_exit_during_initialization("Hard-coded field offset verification failed"); |
3266 } | 3265 } |
3267 | 3266 |
3268 #endif // PRODUCT | 3267 #endif // PRODUCT |
3269 | 3268 |
3269 int InjectedField::compute_offset() { | |
3270 klassOop klass_oop = klass(); | |
3271 for (AllFieldStream fs(instanceKlass::cast(klass_oop)); !fs.done(); fs.next()) { | |
3272 if (!may_be_java && !fs.access_flags().is_internal()) { | |
3273 // Only look at injected fields | |
3274 continue; | |
3275 } | |
3276 if (fs.name() == name() && fs.signature() == signature()) { | |
3277 return fs.offset(); | |
3278 } | |
3279 } | |
3280 ResourceMark rm; | |
3281 tty->print_cr("Invalid layout of %s at %s", instanceKlass::cast(klass_oop)->external_name(), name()->as_C_string()); | |
3282 fatal("Invalid layout of preloaded class"); | |
3283 return -1; | |
3284 } | |
3285 | |
3270 void javaClasses_init() { | 3286 void javaClasses_init() { |
3271 JavaClasses::compute_offsets(); | 3287 JavaClasses::compute_offsets(); |
3272 JavaClasses::check_offsets(); | 3288 JavaClasses::check_offsets(); |
3273 FilteredFieldsMap::initialize(); // must be done after computing offsets. | 3289 FilteredFieldsMap::initialize(); // must be done after computing offsets. |
3274 } | 3290 } |