< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page

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





 675   oop new_obj_oop = nullptr;
 676   if (obj->is_array()) {
 677     const int length = ((arrayOop)obj())->length();
 678     new_obj_oop = Universe::heap()->array_allocate(klass, size, length,
 679                                                    /* do_zero */ true, CHECK_NULL);
 680   } else {
 681     new_obj_oop = Universe::heap()->obj_allocate(klass, size, CHECK_NULL);
 682   }
 683 
 684   HeapAccess<>::clone(obj(), new_obj_oop, size);
 685 
 686   Handle new_obj(THREAD, new_obj_oop);
 687   // Caution: this involves a java upcall, so the clone should be
 688   // "gc-robust" by this stage.
 689   if (klass->has_finalizer()) {
 690     assert(obj->is_instance(), "should be instanceOop");
 691     new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);
 692     new_obj = Handle(THREAD, new_obj_oop);
 693   }
 694 

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