我在Java中找到了clone()
方法:Object
protected native Object clone() throws CloneNotSupportedException;
这个方法的来源是否可用?也许在OpenJDK中?
来自 jdk/src/share/native/java/lang/Object.c
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
意味着它是一个函数指针(可能这样做是为了实现特定于平台的本机代码)
为 JVM_Clone 执行 grep 会产生以下结果:
(来自热点/src/share/vm/prims/jvm.cpp)
JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
JVMWrapper("JVM_Clone");
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
const KlassHandle klass (THREAD, obj->klass());
JvmtiVMObjectAllocEventCollector oam;
#ifdef ASSERT
// Just checking that the cloneable flag is set correct
if (obj->is_javaArray()) {
guarantee(klass->is_cloneable(), "all arrays are cloneable");
} else {
guarantee(obj->is_instance(), "should be instanceOop");
bool cloneable = klass->is_subtype_of(SystemDictionary::Cloneable_klass());
guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag");
}
#endif
// Check if class of obj supports the Cloneable interface.
// All arrays are considered to be cloneable (See JLS 20.1.5)
if (!klass->is_cloneable()) {
ResourceMark rm(THREAD);
THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
}
// Make shallow object copy
const int size = obj->size();
oop new_obj = NULL;
if (obj->is_javaArray()) {
const int length = ((arrayOop)obj())->length();
new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
} else {
new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
}
// 4839641 (4840070): We must do an oop-atomic copy, because if another thread
// is modifying a reference field in the clonee, a non-oop-atomic copy might
// be suspended in the middle of copying the pointer and end up with parts
// of two different pointers in the field. Subsequent dereferences will crash.
// 4846409: an oop-copy of objects with long or double fields or arrays of same
// won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead
// of oops. We know objects are aligned on a minimum of an jlong boundary.
// The same is true of StubRoutines::object_copy and the various oop_copy
// variants, and of the code generated by the inline_native_clone intrinsic.
assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned");
Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj,
(size_t)align_object_size(size) / HeapWordsPerLong);
// Clear the header
new_obj->init_mark();
// Store check (mark entire object and let gc sort it out)
BarrierSet* bs = Universe::heap()->barrier_set();
assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
bs->write_region(MemRegion((HeapWord*)new_obj, size));
// Caution: this involves a java upcall, so the clone should be
// "gc-robust" by this stage.
if (klass->has_finalizer()) {
assert(obj->is_instance(), "should be instanceOop");
new_obj = instanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL);
}
return JNIHandles::make_local(env, oop(new_obj));
JVM_END
我找到了这些文件,但他们所做的只是从其他地方导入函数。我找不到实际来源(尝试询问 Hotspot 开发人员)。
编辑:这是在线实际来源的链接(感谢 user439407 找到它所在的文件)