Mercurial > hg > graal-jvmci-8
comparison src/share/vm/prims/jvm.cpp @ 20677:fe34c5ab0b35
8042235: redefining method used by multiple MethodHandles crashes VM
Summary: note all MemberNames created on internal list for adjusting method entries.
Reviewed-by: sspitsyn, dcubed, lfoltan
author | coleenp |
---|---|
date | Wed, 19 Nov 2014 13:02:11 -0500 |
parents | 4cb90023bf2b |
children | d4caf9c96afd |
comparison
equal
deleted
inserted
replaced
20666:bee8095780db | 20677:fe34c5ab0b35 |
---|---|
601 THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name()); | 601 THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name()); |
602 } | 602 } |
603 | 603 |
604 // Make shallow object copy | 604 // Make shallow object copy |
605 const int size = obj->size(); | 605 const int size = obj->size(); |
606 oop new_obj = NULL; | 606 oop new_obj_oop = NULL; |
607 if (obj->is_array()) { | 607 if (obj->is_array()) { |
608 const int length = ((arrayOop)obj())->length(); | 608 const int length = ((arrayOop)obj())->length(); |
609 new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL); | 609 new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL); |
610 } else { | 610 } else { |
611 new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); | 611 new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); |
612 } | 612 } |
613 | |
613 // 4839641 (4840070): We must do an oop-atomic copy, because if another thread | 614 // 4839641 (4840070): We must do an oop-atomic copy, because if another thread |
614 // is modifying a reference field in the clonee, a non-oop-atomic copy might | 615 // is modifying a reference field in the clonee, a non-oop-atomic copy might |
615 // be suspended in the middle of copying the pointer and end up with parts | 616 // be suspended in the middle of copying the pointer and end up with parts |
616 // of two different pointers in the field. Subsequent dereferences will crash. | 617 // of two different pointers in the field. Subsequent dereferences will crash. |
617 // 4846409: an oop-copy of objects with long or double fields or arrays of same | 618 // 4846409: an oop-copy of objects with long or double fields or arrays of same |
618 // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead | 619 // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead |
619 // of oops. We know objects are aligned on a minimum of an jlong boundary. | 620 // of oops. We know objects are aligned on a minimum of an jlong boundary. |
620 // The same is true of StubRoutines::object_copy and the various oop_copy | 621 // The same is true of StubRoutines::object_copy and the various oop_copy |
621 // variants, and of the code generated by the inline_native_clone intrinsic. | 622 // variants, and of the code generated by the inline_native_clone intrinsic. |
622 assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned"); | 623 assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned"); |
623 Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj, | 624 Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj_oop, |
624 (size_t)align_object_size(size) / HeapWordsPerLong); | 625 (size_t)align_object_size(size) / HeapWordsPerLong); |
625 // Clear the header | 626 // Clear the header |
626 new_obj->init_mark(); | 627 new_obj_oop->init_mark(); |
627 | 628 |
628 // Store check (mark entire object and let gc sort it out) | 629 // Store check (mark entire object and let gc sort it out) |
629 BarrierSet* bs = Universe::heap()->barrier_set(); | 630 BarrierSet* bs = Universe::heap()->barrier_set(); |
630 assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); | 631 assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); |
631 bs->write_region(MemRegion((HeapWord*)new_obj, size)); | 632 bs->write_region(MemRegion((HeapWord*)new_obj_oop, size)); |
633 | |
634 Handle new_obj(THREAD, new_obj_oop); | |
635 // Special handling for MemberNames. Since they contain Method* metadata, they | |
636 // must be registered so that RedefineClasses can fix metadata contained in them. | |
637 if (java_lang_invoke_MemberName::is_instance(new_obj()) && | |
638 java_lang_invoke_MemberName::is_method(new_obj())) { | |
639 Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(new_obj()); | |
640 // MemberName may be unresolved, so doesn't need registration until resolved. | |
641 if (method != NULL) { | |
642 methodHandle m(THREAD, method); | |
643 // This can safepoint and redefine method, so need both new_obj and method | |
644 // in a handle, for two different reasons. new_obj can move, method can be | |
645 // deleted if nothing is using it on the stack. | |
646 m->method_holder()->add_member_name(new_obj()); | |
647 } | |
648 } | |
632 | 649 |
633 // Caution: this involves a java upcall, so the clone should be | 650 // Caution: this involves a java upcall, so the clone should be |
634 // "gc-robust" by this stage. | 651 // "gc-robust" by this stage. |
635 if (klass->has_finalizer()) { | 652 if (klass->has_finalizer()) { |
636 assert(obj->is_instance(), "should be instanceOop"); | 653 assert(obj->is_instance(), "should be instanceOop"); |
637 new_obj = InstanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL); | 654 new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL); |
638 } | 655 new_obj = Handle(THREAD, new_obj_oop); |
639 | 656 } |
640 return JNIHandles::make_local(env, oop(new_obj)); | 657 |
658 return JNIHandles::make_local(env, new_obj()); | |
641 JVM_END | 659 JVM_END |
642 | 660 |
643 // java.lang.Compiler //////////////////////////////////////////////////// | 661 // java.lang.Compiler //////////////////////////////////////////////////// |
644 | 662 |
645 // The initial cuts of the HotSpot VM will not support JITs, and all existing | 663 // The initial cuts of the HotSpot VM will not support JITs, and all existing |