【问题标题】:Is it possible to find the source for a Java native method?是否可以找到 Java 本机方法的来源?
【发布时间】:2012-08-15 11:11:37
【问题描述】:

我在Java中找到了Objectclone()方法:

 protected native Object clone() throws CloneNotSupportedException;

此方法的来源可用吗?也许在OpenJDK

【问题讨论】:

    标签: java methods native


    【解决方案1】:

    我找到了这些文件,但他们所做的只是从其他地方导入函数。我找不到实际来源(尝试询问 Hotspot 开发人员)。

    Object.c jvm.h

    编辑:Here's a link to the actual source online(感谢 user439407 找到它所在的文件)

    【讨论】:

      【解决方案2】:

      来自 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
      

      【讨论】:

      • 啊 grep,你的 linux 用户真好。我在任何地方都找不到 JVM_Clone 的实际定义。
      • @Antimony - 解决方案在你手中 :-)
      • @Antimony:正如 Stephen C 所说,解决方案掌握在您手中,赢了findstr 就派上用场了。
      猜你喜欢
      • 2011-05-25
      • 2011-09-24
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 2012-07-05
      相关资源
      最近更新 更多