< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page

 663   if (obj->is_array()) {
 664     guarantee(klass->is_cloneable(), "all arrays are cloneable");
 665   } else {
 666     guarantee(obj->is_instance(), "should be instanceOop");
 667     bool cloneable = klass->is_subtype_of(vmClasses::Cloneable_klass());
 668     guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag");
 669   }
 670 #endif
 671 
 672   // Check if class of obj supports the Cloneable interface.
 673   // All arrays are considered to be cloneable (See JLS 20.1.5).
 674   // All j.l.r.Reference classes are considered non-cloneable.
 675   if (!klass->is_cloneable() ||
 676       (klass->is_instance_klass() &&
 677        InstanceKlass::cast(klass)->reference_type() != REF_NONE)) {
 678     ResourceMark rm(THREAD);
 679     THROW_MSG_NULL(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
 680   }
 681 
 682   // Make shallow object copy
 683   const size_t size = obj->size();





 684   oop new_obj_oop = nullptr;
 685   if (obj->is_array()) {
 686     const int length = ((arrayOop)obj())->length();
 687     new_obj_oop = Universe::heap()->array_allocate(klass, size, length,
 688                                                    /* do_zero */ true, CHECK_NULL);
 689   } else {
 690     new_obj_oop = Universe::heap()->obj_allocate(klass, size, CHECK_NULL);
 691   }
 692 
 693   HeapAccess<>::clone(obj(), new_obj_oop, size);
 694 
 695   Handle new_obj(THREAD, new_obj_oop);
 696   // Caution: this involves a java upcall, so the clone should be
 697   // "gc-robust" by this stage.
 698   if (klass->has_finalizer()) {
 699     assert(obj->is_instance(), "should be instanceOop");
 700     new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);
 701     new_obj = Handle(THREAD, new_obj_oop);
 702   }
 703 

 663   if (obj->is_array()) {
 664     guarantee(klass->is_cloneable(), "all arrays are cloneable");
 665   } else {
 666     guarantee(obj->is_instance(), "should be instanceOop");
 667     bool cloneable = klass->is_subtype_of(vmClasses::Cloneable_klass());
 668     guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag");
 669   }
 670 #endif
 671 
 672   // Check if class of obj supports the Cloneable interface.
 673   // All arrays are considered to be cloneable (See JLS 20.1.5).
 674   // All j.l.r.Reference classes are considered non-cloneable.
 675   if (!klass->is_cloneable() ||
 676       (klass->is_instance_klass() &&
 677        InstanceKlass::cast(klass)->reference_type() != REF_NONE)) {
 678     ResourceMark rm(THREAD);
 679     THROW_MSG_NULL(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
 680   }
 681 
 682   // Make shallow object copy
 683   // With compact object headers, the original might have been expanded by GC
 684   // for the identity hash. The clone must be allocated at the base size, since
 685   // it will get a fresh (not-hashed, not-expanded) mark word.
 686   const size_t size = UseCompactObjectHeaders
 687     ? obj->base_size_given_klass(obj->mark(), klass)
 688     : obj->size();
 689   oop new_obj_oop = nullptr;
 690   if (obj->is_array()) {
 691     const int length = ((arrayOop)obj())->length();
 692     new_obj_oop = Universe::heap()->array_allocate(klass, size, length,
 693                                                    /* do_zero */ true, CHECK_NULL);
 694   } else {
 695     new_obj_oop = Universe::heap()->obj_allocate(klass, size, CHECK_NULL);
 696   }
 697 
 698   HeapAccess<>::clone(obj(), new_obj_oop, size);
 699 
 700   Handle new_obj(THREAD, new_obj_oop);
 701   // Caution: this involves a java upcall, so the clone should be
 702   // "gc-robust" by this stage.
 703   if (klass->has_finalizer()) {
 704     assert(obj->is_instance(), "should be instanceOop");
 705     new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);
 706     new_obj = Handle(THREAD, new_obj_oop);
 707   }
 708 
< prev index next >