Mercurial > hg > truffle
comparison src/share/vm/classfile/javaClasses.cpp @ 2376:c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
Reviewed-by: kvn, coleenp, twisti, stefank
author | never |
---|---|
date | Fri, 18 Mar 2011 16:00:34 -0700 |
parents | 8033953d67ff |
children | b099aaf51bf8 |
comparison
equal
deleted
inserted
replaced
2375:d673ef06fe96 | 2376:c7f3d0b4570f |
---|---|
31 #include "interpreter/interpreter.hpp" | 31 #include "interpreter/interpreter.hpp" |
32 #include "memory/oopFactory.hpp" | 32 #include "memory/oopFactory.hpp" |
33 #include "memory/resourceArea.hpp" | 33 #include "memory/resourceArea.hpp" |
34 #include "memory/universe.inline.hpp" | 34 #include "memory/universe.inline.hpp" |
35 #include "oops/instanceKlass.hpp" | 35 #include "oops/instanceKlass.hpp" |
36 #include "oops/instanceMirrorKlass.hpp" | |
36 #include "oops/klass.hpp" | 37 #include "oops/klass.hpp" |
37 #include "oops/klassOop.hpp" | 38 #include "oops/klassOop.hpp" |
38 #include "oops/methodOop.hpp" | 39 #include "oops/methodOop.hpp" |
39 #include "oops/symbol.hpp" | 40 #include "oops/symbol.hpp" |
40 #include "oops/typeArrayOop.hpp" | 41 #include "oops/typeArrayOop.hpp" |
389 } | 390 } |
390 st->print("\""); | 391 st->print("\""); |
391 } | 392 } |
392 } | 393 } |
393 | 394 |
395 static void initialize_static_field(fieldDescriptor* fd, TRAPS) { | |
396 Handle mirror (THREAD, fd->field_holder()->java_mirror()); | |
397 assert(mirror.not_null() && fd->is_static(), "just checking"); | |
398 if (fd->has_initial_value()) { | |
399 BasicType t = fd->field_type(); | |
400 switch (t) { | |
401 case T_BYTE: | |
402 mirror()->byte_field_put(fd->offset(), fd->int_initial_value()); | |
403 break; | |
404 case T_BOOLEAN: | |
405 mirror()->bool_field_put(fd->offset(), fd->int_initial_value()); | |
406 break; | |
407 case T_CHAR: | |
408 mirror()->char_field_put(fd->offset(), fd->int_initial_value()); | |
409 break; | |
410 case T_SHORT: | |
411 mirror()->short_field_put(fd->offset(), fd->int_initial_value()); | |
412 break; | |
413 case T_INT: | |
414 mirror()->int_field_put(fd->offset(), fd->int_initial_value()); | |
415 break; | |
416 case T_FLOAT: | |
417 mirror()->float_field_put(fd->offset(), fd->float_initial_value()); | |
418 break; | |
419 case T_DOUBLE: | |
420 mirror()->double_field_put(fd->offset(), fd->double_initial_value()); | |
421 break; | |
422 case T_LONG: | |
423 mirror()->long_field_put(fd->offset(), fd->long_initial_value()); | |
424 break; | |
425 case T_OBJECT: | |
426 { | |
427 #ifdef ASSERT | |
428 TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK); | |
429 assert(fd->signature() == sym, "just checking"); | |
430 #endif | |
431 oop string = fd->string_initial_value(CHECK); | |
432 mirror()->obj_field_put(fd->offset(), string); | |
433 } | |
434 break; | |
435 default: | |
436 THROW_MSG(vmSymbols::java_lang_ClassFormatError(), | |
437 "Illegal ConstantValue attribute in class file"); | |
438 } | |
439 } | |
440 } | |
441 | |
442 | |
443 // During bootstrap, java.lang.Class wasn't loaded so static field | |
444 // offsets were computed without the size added it. Go back and | |
445 // update all the static field offsets to included the size. | |
446 static void fixup_static_field(fieldDescriptor* fd, TRAPS) { | |
447 if (fd->is_static()) { | |
448 int real_offset = fd->offset() + instanceMirrorKlass::offset_of_static_fields(); | |
449 typeArrayOop fields = instanceKlass::cast(fd->field_holder())->fields(); | |
450 fields->short_at_put(fd->index() + instanceKlass::low_offset, extract_low_short_from_int(real_offset)); | |
451 fields->short_at_put(fd->index() + instanceKlass::high_offset, extract_high_short_from_int(real_offset)); | |
452 } | |
453 } | |
454 | |
455 void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) { | |
456 assert(instanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already"); | |
457 | |
458 if (k->oop_is_instance()) { | |
459 // Fixup the offsets | |
460 instanceKlass::cast(k())->do_local_static_fields(&fixup_static_field, CHECK); | |
461 } | |
462 create_mirror(k, CHECK); | |
463 } | |
394 | 464 |
395 oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) { | 465 oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) { |
396 assert(k->java_mirror() == NULL, "should only assign mirror once"); | 466 assert(k->java_mirror() == NULL, "should only assign mirror once"); |
397 // Use this moment of initialization to cache modifier_flags also, | 467 // Use this moment of initialization to cache modifier_flags also, |
398 // to support Class.getModifiers(). Instance classes recalculate | 468 // to support Class.getModifiers(). Instance classes recalculate |
399 // the cached flags after the class file is parsed, but before the | 469 // the cached flags after the class file is parsed, but before the |
400 // class is put into the system dictionary. | 470 // class is put into the system dictionary. |
401 int computed_modifiers = k->compute_modifier_flags(CHECK_0); | 471 int computed_modifiers = k->compute_modifier_flags(CHECK_0); |
402 k->set_modifier_flags(computed_modifiers); | 472 k->set_modifier_flags(computed_modifiers); |
403 if (SystemDictionary::Class_klass_loaded()) { | 473 if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) { |
404 // Allocate mirror (java.lang.Class instance) | 474 // Allocate mirror (java.lang.Class instance) |
405 Handle mirror = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0); | 475 Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0); |
406 // Setup indirections | 476 // Setup indirections |
407 mirror->obj_field_put(klass_offset, k()); | 477 mirror->obj_field_put(klass_offset, k()); |
408 k->set_java_mirror(mirror()); | 478 k->set_java_mirror(mirror()); |
479 | |
480 instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass()); | |
481 java_lang_Class::set_oop_size(mirror(), mk->instance_size(k)); | |
482 java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); | |
483 | |
409 // It might also have a component mirror. This mirror must already exist. | 484 // It might also have a component mirror. This mirror must already exist. |
410 if (k->oop_is_javaArray()) { | 485 if (k->oop_is_javaArray()) { |
411 Handle comp_mirror; | 486 Handle comp_mirror; |
412 if (k->oop_is_typeArray()) { | 487 if (k->oop_is_typeArray()) { |
413 BasicType type = typeArrayKlass::cast(k->as_klassOop())->element_type(); | 488 BasicType type = typeArrayKlass::cast(k->as_klassOop())->element_type(); |
426 if (comp_mirror.not_null()) { | 501 if (comp_mirror.not_null()) { |
427 // Two-way link between the array klass and its component mirror: | 502 // Two-way link between the array klass and its component mirror: |
428 arrayKlass::cast(k->as_klassOop())->set_component_mirror(comp_mirror()); | 503 arrayKlass::cast(k->as_klassOop())->set_component_mirror(comp_mirror()); |
429 set_array_klass(comp_mirror(), k->as_klassOop()); | 504 set_array_klass(comp_mirror(), k->as_klassOop()); |
430 } | 505 } |
506 } else if (k->oop_is_instance()) { | |
507 // Initialize static fields | |
508 instanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL); | |
431 } | 509 } |
432 return mirror(); | 510 return mirror(); |
433 } else { | 511 } else { |
434 return NULL; | 512 return NULL; |
435 } | 513 } |
436 } | 514 } |
437 | 515 |
438 | 516 |
517 | |
518 int java_lang_Class::oop_size(oop java_class) { | |
519 assert(oop_size_offset != 0, "must be set"); | |
520 return java_class->int_field(oop_size_offset); | |
521 } | |
522 void java_lang_Class::set_oop_size(oop java_class, int size) { | |
523 assert(oop_size_offset != 0, "must be set"); | |
524 java_class->int_field_put(oop_size_offset, size); | |
525 } | |
526 int java_lang_Class::static_oop_field_count(oop java_class) { | |
527 assert(static_oop_field_count_offset != 0, "must be set"); | |
528 return java_class->int_field(static_oop_field_count_offset); | |
529 } | |
530 void java_lang_Class::set_static_oop_field_count(oop java_class, int size) { | |
531 assert(static_oop_field_count_offset != 0, "must be set"); | |
532 java_class->int_field_put(static_oop_field_count_offset, size); | |
533 } | |
534 | |
535 | |
536 | |
537 | |
439 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { | 538 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { |
440 // This should be improved by adding a field at the Java level or by | 539 // This should be improved by adding a field at the Java level or by |
441 // introducing a new VM klass (see comment in ClassFileParser) | 540 // introducing a new VM klass (see comment in ClassFileParser) |
442 oop java_class = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0); | 541 oop java_class = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance((oop)NULL, CHECK_0); |
443 if (type != T_VOID) { | 542 if (type != T_VOID) { |
444 klassOop aklass = Universe::typeArrayKlassObj(type); | 543 klassOop aklass = Universe::typeArrayKlassObj(type); |
445 assert(aklass != NULL, "correct bootstrap"); | 544 assert(aklass != NULL, "correct bootstrap"); |
446 set_array_klass(java_class, aklass); | 545 set_array_klass(java_class, aklass); |
447 } | 546 } |
547 instanceMirrorKlass* mk = instanceMirrorKlass::cast(SystemDictionary::Class_klass()); | |
548 java_lang_Class::set_oop_size(java_class, mk->instance_size(oop(NULL))); | |
549 java_lang_Class::set_static_oop_field_count(java_class, 0); | |
448 return java_class; | 550 return java_class; |
449 } | 551 } |
450 | 552 |
451 | 553 |
452 klassOop java_lang_Class::as_klassOop(oop java_class) { | 554 klassOop java_lang_Class::as_klassOop(oop java_class) { |
453 //%note memory_2 | 555 //%note memory_2 |
556 assert(java_lang_Class::is_instance(java_class), "must be a Class object"); | |
454 klassOop k = klassOop(java_class->obj_field(klass_offset)); | 557 klassOop k = klassOop(java_class->obj_field(klass_offset)); |
455 assert(k == NULL || k->is_klass(), "type check"); | 558 assert(k == NULL || k->is_klass(), "type check"); |
456 return k; | 559 return k; |
457 } | 560 } |
458 | 561 |
2150 | 2253 |
2151 | 2254 |
2152 // Support for java_lang_ref_Reference | 2255 // Support for java_lang_ref_Reference |
2153 oop java_lang_ref_Reference::pending_list_lock() { | 2256 oop java_lang_ref_Reference::pending_list_lock() { |
2154 instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass()); | 2257 instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass()); |
2155 char *addr = (((char *)ik->start_of_static_fields()) + static_lock_offset); | 2258 address addr = ik->static_field_addr(static_lock_offset); |
2156 if (UseCompressedOops) { | 2259 if (UseCompressedOops) { |
2157 return oopDesc::load_decode_heap_oop((narrowOop *)addr); | 2260 return oopDesc::load_decode_heap_oop((narrowOop *)addr); |
2158 } else { | 2261 } else { |
2159 return oopDesc::load_decode_heap_oop((oop*)addr); | 2262 return oopDesc::load_decode_heap_oop((oop*)addr); |
2160 } | 2263 } |
2161 } | 2264 } |
2162 | 2265 |
2163 HeapWord *java_lang_ref_Reference::pending_list_addr() { | 2266 HeapWord *java_lang_ref_Reference::pending_list_addr() { |
2164 instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass()); | 2267 instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass()); |
2165 char *addr = (((char *)ik->start_of_static_fields()) + static_pending_offset); | 2268 address addr = ik->static_field_addr(static_pending_offset); |
2166 // XXX This might not be HeapWord aligned, almost rather be char *. | 2269 // XXX This might not be HeapWord aligned, almost rather be char *. |
2167 return (HeapWord*)addr; | 2270 return (HeapWord*)addr; |
2168 } | 2271 } |
2169 | 2272 |
2170 oop java_lang_ref_Reference::pending_list() { | 2273 oop java_lang_ref_Reference::pending_list() { |
2183 return ref->long_field(timestamp_offset); | 2286 return ref->long_field(timestamp_offset); |
2184 } | 2287 } |
2185 | 2288 |
2186 jlong java_lang_ref_SoftReference::clock() { | 2289 jlong java_lang_ref_SoftReference::clock() { |
2187 instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass()); | 2290 instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass()); |
2188 int offset = ik->offset_of_static_fields() + static_clock_offset; | 2291 jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset); |
2189 | 2292 return *offset; |
2190 return SystemDictionary::SoftReference_klass()->long_field(offset); | |
2191 } | 2293 } |
2192 | 2294 |
2193 void java_lang_ref_SoftReference::set_clock(jlong value) { | 2295 void java_lang_ref_SoftReference::set_clock(jlong value) { |
2194 instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass()); | 2296 instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass()); |
2195 int offset = ik->offset_of_static_fields() + static_clock_offset; | 2297 jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset); |
2196 | 2298 *offset = value; |
2197 SystemDictionary::SoftReference_klass()->long_field_put(offset, value); | |
2198 } | 2299 } |
2199 | 2300 |
2200 | 2301 |
2201 // Support for java_lang_invoke_MethodHandle | 2302 // Support for java_lang_invoke_MethodHandle |
2202 | 2303 |
2623 return loader; | 2724 return loader; |
2624 } | 2725 } |
2625 | 2726 |
2626 | 2727 |
2627 // Support for java_lang_System | 2728 // Support for java_lang_System |
2628 | |
2629 void java_lang_System::compute_offsets() { | |
2630 assert(offset_of_static_fields == 0, "offsets should be initialized only once"); | |
2631 | |
2632 instanceKlass* ik = instanceKlass::cast(SystemDictionary::System_klass()); | |
2633 offset_of_static_fields = ik->offset_of_static_fields(); | |
2634 } | |
2635 | |
2636 int java_lang_System::in_offset_in_bytes() { | 2729 int java_lang_System::in_offset_in_bytes() { |
2637 return (offset_of_static_fields + static_in_offset); | 2730 return (instanceMirrorKlass::offset_of_static_fields() + static_in_offset); |
2638 } | 2731 } |
2639 | 2732 |
2640 | 2733 |
2641 int java_lang_System::out_offset_in_bytes() { | 2734 int java_lang_System::out_offset_in_bytes() { |
2642 return (offset_of_static_fields + static_out_offset); | 2735 return (instanceMirrorKlass::offset_of_static_fields() + static_out_offset); |
2643 } | 2736 } |
2644 | 2737 |
2645 | 2738 |
2646 int java_lang_System::err_offset_in_bytes() { | 2739 int java_lang_System::err_offset_in_bytes() { |
2647 return (offset_of_static_fields + static_err_offset); | 2740 return (instanceMirrorKlass::offset_of_static_fields() + static_err_offset); |
2648 } | 2741 } |
2649 | 2742 |
2650 | 2743 |
2651 | 2744 |
2652 int java_lang_String::value_offset; | 2745 int java_lang_String::value_offset; |
2655 int java_lang_String::hash_offset; | 2748 int java_lang_String::hash_offset; |
2656 int java_lang_Class::klass_offset; | 2749 int java_lang_Class::klass_offset; |
2657 int java_lang_Class::array_klass_offset; | 2750 int java_lang_Class::array_klass_offset; |
2658 int java_lang_Class::resolved_constructor_offset; | 2751 int java_lang_Class::resolved_constructor_offset; |
2659 int java_lang_Class::number_of_fake_oop_fields; | 2752 int java_lang_Class::number_of_fake_oop_fields; |
2753 int java_lang_Class::oop_size_offset; | |
2754 int java_lang_Class::static_oop_field_count_offset; | |
2660 int java_lang_Throwable::backtrace_offset; | 2755 int java_lang_Throwable::backtrace_offset; |
2661 int java_lang_Throwable::detailMessage_offset; | 2756 int java_lang_Throwable::detailMessage_offset; |
2662 int java_lang_Throwable::cause_offset; | 2757 int java_lang_Throwable::cause_offset; |
2663 int java_lang_Throwable::stackTrace_offset; | 2758 int java_lang_Throwable::stackTrace_offset; |
2664 int java_lang_reflect_AccessibleObject::override_offset; | 2759 int java_lang_reflect_AccessibleObject::override_offset; |
2698 int java_lang_ref_Reference::static_pending_offset; | 2793 int java_lang_ref_Reference::static_pending_offset; |
2699 int java_lang_ref_Reference::number_of_fake_oop_fields; | 2794 int java_lang_ref_Reference::number_of_fake_oop_fields; |
2700 int java_lang_ref_SoftReference::timestamp_offset; | 2795 int java_lang_ref_SoftReference::timestamp_offset; |
2701 int java_lang_ref_SoftReference::static_clock_offset; | 2796 int java_lang_ref_SoftReference::static_clock_offset; |
2702 int java_lang_ClassLoader::parent_offset; | 2797 int java_lang_ClassLoader::parent_offset; |
2703 int java_lang_System::offset_of_static_fields; | |
2704 int java_lang_System::static_in_offset; | 2798 int java_lang_System::static_in_offset; |
2705 int java_lang_System::static_out_offset; | 2799 int java_lang_System::static_out_offset; |
2706 int java_lang_System::static_err_offset; | 2800 int java_lang_System::static_err_offset; |
2707 int java_lang_StackTraceElement::declaringClass_offset; | 2801 int java_lang_StackTraceElement::declaringClass_offset; |
2708 int java_lang_StackTraceElement::methodName_offset; | 2802 int java_lang_StackTraceElement::methodName_offset; |
2815 java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header; | 2909 java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header; |
2816 java_lang_String::offset_offset = java_lang_String::hc_offset_offset * x + header; | 2910 java_lang_String::offset_offset = java_lang_String::hc_offset_offset * x + header; |
2817 java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint); | 2911 java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint); |
2818 java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint); | 2912 java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint); |
2819 | 2913 |
2820 // Do the Class Class | 2914 { |
2821 java_lang_Class::klass_offset = java_lang_Class::hc_klass_offset * x + header; | 2915 // Do the Class Class |
2822 java_lang_Class::array_klass_offset = java_lang_Class::hc_array_klass_offset * x + header; | 2916 int offset = header; |
2823 java_lang_Class::resolved_constructor_offset = java_lang_Class::hc_resolved_constructor_offset * x + header; | 2917 java_lang_Class::oop_size_offset = header; |
2918 offset += BytesPerInt; | |
2919 java_lang_Class::static_oop_field_count_offset = offset; | |
2920 offset = align_size_up(offset + BytesPerInt, x); | |
2921 java_lang_Class::klass_offset = offset; | |
2922 offset += x; | |
2923 java_lang_Class::array_klass_offset = offset; | |
2924 offset += x; | |
2925 java_lang_Class::resolved_constructor_offset = offset; | |
2926 } | |
2824 | 2927 |
2825 // This is NOT an offset | 2928 // This is NOT an offset |
2826 java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields; | 2929 java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields; |
2827 | 2930 |
2828 // Throwable Class | 2931 // Throwable Class |
2875 | 2978 |
2876 // Compute non-hard-coded field offsets of all the classes in this file | 2979 // Compute non-hard-coded field offsets of all the classes in this file |
2877 void JavaClasses::compute_offsets() { | 2980 void JavaClasses::compute_offsets() { |
2878 | 2981 |
2879 java_lang_Class::compute_offsets(); | 2982 java_lang_Class::compute_offsets(); |
2880 java_lang_System::compute_offsets(); | |
2881 java_lang_Thread::compute_offsets(); | 2983 java_lang_Thread::compute_offsets(); |
2882 java_lang_ThreadGroup::compute_offsets(); | 2984 java_lang_ThreadGroup::compute_offsets(); |
2883 if (EnableMethodHandles) { | 2985 if (EnableMethodHandles) { |
2884 java_lang_invoke_MethodHandle::compute_offsets(); | 2986 java_lang_invoke_MethodHandle::compute_offsets(); |
2885 java_lang_invoke_MemberName::compute_offsets(); | 2987 java_lang_invoke_MemberName::compute_offsets(); |
2959 } | 3061 } |
2960 if (!fd.is_static()) { | 3062 if (!fd.is_static()) { |
2961 tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name); | 3063 tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name); |
2962 return false; | 3064 return false; |
2963 } | 3065 } |
2964 if (fd.offset() == hardcoded_offset + h_klass->offset_of_static_fields()) { | 3066 if (fd.offset() == hardcoded_offset + instanceMirrorKlass::offset_of_static_fields()) { |
2965 return true; | 3067 return true; |
2966 } else { | 3068 } else { |
2967 tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - h_klass->offset_of_static_fields()); | 3069 tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - instanceMirrorKlass::offset_of_static_fields()); |
2968 return false; | 3070 return false; |
2969 } | 3071 } |
2970 } | 3072 } |
2971 | 3073 |
2972 | 3074 |