Is it possible to find the source for a Java native method?

前端 未结 2 1491
梦如初夏
梦如初夏 2020-12-05 21:41

I have found the clone() method of Object in Java:

 protected native Object clone() throws CloneNotSupportedException;
相关标签:
2条回答
  • 2020-12-05 22:14

    I found these files, but all they do is import the function from elsewhere. I can't find the actual source (try asking a Hotspot dev).

    Object.c jvm.h

    Edit: Here's a link to the actual source online (Thanks user439407 for finding which file it was in)

    0 讨论(0)
  • 2020-12-05 22:18

    From 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},
    };
    

    Meaning its a function pointer(probably done so they could implement platform-specific native code)

    doing a grep for JVM_Clone produces, among other things:

    (from hotspot/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
    
    0 讨论(0)
提交回复
热议问题