Objectクラスの実装方法が不思議です。内部状態が示されている方法の例Objectクラスはどのように実装されていますか(hashCodeや内部フィールドなどのメソッド)?
- 方法のhashCode()または(待機)
- 。 たとえば、イントリンシックなロックまたはオブジェクトのwait()を呼び出したスレッドを格納するためのデータ構造体。これらを見つけるために
は、私はOpenJDKのソースをダウンロードして掘るを開始しました。まず最初に、私が出会ったのlang \オブジェクト\ネイティブ\のJava \ \ openjdksrc \ JDK \ SRC \シェアでした。含む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},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
JNIEXPORT jclass JNICALL
Java_java_lang_Object_getClass(JNIEnv *env, jobject this)
{
if (this == NULL) {
JNU_ThrowNullPointerException(env, NULL);
return 0;
} else {
return (*env)->GetObjectClass(env, this);
}
}
と私の理解のために、方法[]配列は、オブジェクトのメソッドのネイティブ実装との間のマッピングを定義します。たとえば、ObjectのhashCode()はJVM_IHashCode関数にマップされます。 JVM_IHashCodeは、\ openjdksrc \ hotspot \ src \ share \ vm \ prims \ jvm.cppに実装されています。そして、私の最初の質問です。 これは既にVM自体の一部です(\ openjdksrc \ hotspot \ src \ share \ vmに既に定義されています)。 しかしJVM_IHashCodeのコードに移動することができます:オブジェクトがnullの場合、我々はここに0を返すのはなぜ
JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))
JVMWrapper("JVM_IHashCode");
// as implemented in the classic virtual machine; return 0 if object is NULL
return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;
JVM_END
?私はNPEが投げられるべきだと思います。それ以外の場合、FastHashCodeは\ openjdksrc \ hotspot \ src \ share \ vm \ runtime \ synchronizer.cppから呼び出され、最終的には実際の値を計算するget_next_hashが呼び出されます。 計算されると、質問はどこに保存されますか?
intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) {
...CUT...
ObjectMonitor* monitor = NULL;
markOop temp, test;
intptr_t hash;
markOop mark = ReadStableMark (obj);
...CUT...
if (mark->is_neutral()) {
hash = mark->hash(); // this is a normal header
if (hash) { // if it has hash, just return it
return hash;
}
hash = get_next_hash(Self, obj); // allocate a new hash code
temp = mark->copy_set_hash(hash); // merge the hash code into header
// use (machine word version) atomic operation to install the hash
test = (markOop) Atomic::cmpxchg_ptr(temp, obj->mark_addr(), mark);
if (test == mark) {
return hash;
}
// If atomic operation failed, we must inflate the header
// into heavy weight monitor. We could add more code here
// for fast path, but it does not worth the complexity.
}
...CUT...
return hash;
}
そこでOOPクラス/構造体(?)は、ハッシュ値が格納されているmarkOopクラス/構造体(?)を有しています。 Funilly私はこれらのクラス/構造体を見つけることができません。私は見つけることができたすべてだった:
class oopDesc {
friend class VMStructs;
private:
volatile markOop _mark;
...CUT...
の\ openjdksrc \ホットスポット\のsrc \共有に\ VM \ privateフィールドにmarkOopを持っているようだ をoop.hpp \おっと。 しかし、実際にはコードの残りの部分で言及されている "oop"は何ですか? markOopの定義はどこにありますか?私が対応する発見した:\ VM \おっと\ markOop.hpp \ openjdksrc \ホットスポット\ SRC \共有で
class markOopDesc: public oopDesc
...CUT...
が、それは列挙型の唯一いっぱいで、ハッシュ値ができるフィールドを見つけることができません保存する。 誰かが私の質問の少なくとも一部に答えることができたなら、私は非常に感謝します。ありがとう!
はnull'なので 'のハッシュコードは、実際にゼロにすることになっていますjava.lang.Object) – int3