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); |
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 } |