< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page

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





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

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