Mercurial > hg > graal-compiler
comparison src/share/vm/classfile/javaClasses.cpp @ 17883:9428a0b94204
8028497: SIGSEGV at ClassLoaderData::oops_do(OopClosure*, KlassClosure*, bool)
Summary: Keep class in CLD::_klasses list and mirror created for CDS classes if OOM during restore_shareable_info(). This keeps pointers consistent for CMS.
Reviewed-by: ehelin, stefank, jmasa, iklam
author | coleenp |
---|---|
date | Tue, 15 Apr 2014 17:02:20 -0400 |
parents | 07f8c2a453f8 |
children | 78bbf4d43a14 |
comparison
equal
deleted
inserted
replaced
17876:9c3dc501b5eb | 17883:9428a0b94204 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
480 } | 480 } |
481 st->print("\""); | 481 st->print("\""); |
482 } | 482 } |
483 } | 483 } |
484 | 484 |
485 static void initialize_static_field(fieldDescriptor* fd, TRAPS) { | 485 |
486 Handle mirror (THREAD, fd->field_holder()->java_mirror()); | 486 static void initialize_static_field(fieldDescriptor* fd, Handle mirror, TRAPS) { |
487 assert(mirror.not_null() && fd->is_static(), "just checking"); | 487 assert(mirror.not_null() && fd->is_static(), "just checking"); |
488 if (fd->has_initial_value()) { | 488 if (fd->has_initial_value()) { |
489 BasicType t = fd->field_type(); | 489 BasicType t = fd->field_type(); |
490 switch (t) { | 490 switch (t) { |
491 case T_BYTE: | 491 case T_BYTE: |
548 } | 548 } |
549 } | 549 } |
550 create_mirror(k, Handle(NULL), CHECK); | 550 create_mirror(k, Handle(NULL), CHECK); |
551 } | 551 } |
552 | 552 |
553 oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) { | 553 void java_lang_Class::initialize_mirror_fields(KlassHandle k, |
554 Handle mirror, | |
555 Handle protection_domain, | |
556 TRAPS) { | |
557 // Allocate a simple java object for a lock. | |
558 // This needs to be a java object because during class initialization | |
559 // it can be held across a java call. | |
560 typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK); | |
561 set_init_lock(mirror(), r); | |
562 | |
563 // Set protection domain also | |
564 set_protection_domain(mirror(), protection_domain()); | |
565 | |
566 // Initialize static fields | |
567 InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, mirror, CHECK); | |
568 } | |
569 | |
570 void java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) { | |
554 assert(k->java_mirror() == NULL, "should only assign mirror once"); | 571 assert(k->java_mirror() == NULL, "should only assign mirror once"); |
555 // Use this moment of initialization to cache modifier_flags also, | 572 // Use this moment of initialization to cache modifier_flags also, |
556 // to support Class.getModifiers(). Instance classes recalculate | 573 // to support Class.getModifiers(). Instance classes recalculate |
557 // the cached flags after the class file is parsed, but before the | 574 // the cached flags after the class file is parsed, but before the |
558 // class is put into the system dictionary. | 575 // class is put into the system dictionary. |
559 int computed_modifiers = k->compute_modifier_flags(CHECK_0); | 576 int computed_modifiers = k->compute_modifier_flags(CHECK); |
560 k->set_modifier_flags(computed_modifiers); | 577 k->set_modifier_flags(computed_modifiers); |
561 // Class_klass has to be loaded because it is used to allocate | 578 // Class_klass has to be loaded because it is used to allocate |
562 // the mirror. | 579 // the mirror. |
563 if (SystemDictionary::Class_klass_loaded()) { | 580 if (SystemDictionary::Class_klass_loaded()) { |
564 // Allocate mirror (java.lang.Class instance) | 581 // Allocate mirror (java.lang.Class instance) |
565 Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0); | 582 Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK); |
583 | |
584 // Setup indirection from mirror->klass | |
585 if (!k.is_null()) { | |
586 java_lang_Class::set_klass(mirror(), k()); | |
587 } | |
566 | 588 |
567 InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass()); | 589 InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass()); |
590 assert(oop_size(mirror()) == mk->instance_size(k), "should have been set"); | |
591 | |
568 java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); | 592 java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); |
569 | 593 |
570 // It might also have a component mirror. This mirror must already exist. | 594 // It might also have a component mirror. This mirror must already exist. |
571 if (k->oop_is_array()) { | 595 if (k->oop_is_array()) { |
572 Handle comp_mirror; | 596 Handle comp_mirror; |
575 comp_mirror = Universe::java_mirror(type); | 599 comp_mirror = Universe::java_mirror(type); |
576 } else { | 600 } else { |
577 assert(k->oop_is_objArray(), "Must be"); | 601 assert(k->oop_is_objArray(), "Must be"); |
578 Klass* element_klass = ObjArrayKlass::cast(k())->element_klass(); | 602 Klass* element_klass = ObjArrayKlass::cast(k())->element_klass(); |
579 assert(element_klass != NULL, "Must have an element klass"); | 603 assert(element_klass != NULL, "Must have an element klass"); |
580 comp_mirror = element_klass->java_mirror(); | 604 comp_mirror = element_klass->java_mirror(); |
581 } | 605 } |
582 assert(comp_mirror.not_null(), "must have a mirror"); | 606 assert(comp_mirror.not_null(), "must have a mirror"); |
583 | 607 |
584 // Two-way link between the array klass and its component mirror: | 608 // Two-way link between the array klass and its component mirror: |
585 ArrayKlass::cast(k())->set_component_mirror(comp_mirror()); | 609 ArrayKlass::cast(k())->set_component_mirror(comp_mirror()); |
586 set_array_klass(comp_mirror(), k()); | 610 set_array_klass(comp_mirror(), k()); |
587 } else { | 611 } else { |
588 assert(k->oop_is_instance(), "Must be"); | 612 assert(k->oop_is_instance(), "Must be"); |
589 | 613 |
590 // Allocate a simple java object for a lock. | 614 initialize_mirror_fields(k, mirror, protection_domain, THREAD); |
591 // This needs to be a java object because during class initialization | 615 if (HAS_PENDING_EXCEPTION) { |
592 // it can be held across a java call. | 616 // If any of the fields throws an exception like OOM remove the klass field |
593 typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL); | 617 // from the mirror so GC doesn't follow it after the klass has been deallocated. |
594 set_init_lock(mirror(), r); | 618 // This mirror looks like a primitive type, which logically it is because it |
595 | 619 // it represents no class. |
596 // Set protection domain also | 620 java_lang_Class::set_klass(mirror(), NULL); |
597 set_protection_domain(mirror(), protection_domain()); | 621 return; |
598 | 622 } |
599 // Initialize static fields | 623 } |
600 InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL); | 624 |
601 } | 625 // Setup indirection from klass->mirror last |
602 return mirror(); | 626 // after any exceptions can happen during allocations. |
627 if (!k.is_null()) { | |
628 k->set_java_mirror(mirror()); | |
629 } | |
603 } else { | 630 } else { |
604 if (fixup_mirror_list() == NULL) { | 631 if (fixup_mirror_list() == NULL) { |
605 GrowableArray<Klass*>* list = | 632 GrowableArray<Klass*>* list = |
606 new (ResourceObj::C_HEAP, mtClass) GrowableArray<Klass*>(40, true); | 633 new (ResourceObj::C_HEAP, mtClass) GrowableArray<Klass*>(40, true); |
607 set_fixup_mirror_list(list); | 634 set_fixup_mirror_list(list); |
608 } | 635 } |
609 fixup_mirror_list()->push(k()); | 636 fixup_mirror_list()->push(k()); |
610 return NULL; | 637 } |
611 } | 638 } |
612 } | |
613 | |
614 | 639 |
615 | 640 |
616 int java_lang_Class::oop_size(oop java_class) { | 641 int java_lang_Class::oop_size(oop java_class) { |
617 assert(_oop_size_offset != 0, "must be set"); | 642 assert(_oop_size_offset != 0, "must be set"); |
618 return java_class->int_field(_oop_size_offset); | 643 return java_class->int_field(_oop_size_offset); |