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