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 |