Top


定義場所(file name)

hotspot/src/share/vm/classfile/verifier.cpp

名前(function name)

Symbol* Verifier::inference_verify(
    instanceKlassHandle klass, char* message, size_t message_len, TRAPS) {

本体部(body)

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      JavaThread* thread = (JavaThread*)THREAD;
      JNIEnv *env = thread->jni_environment();

  {- -------------------------------------------
  (1) verify 処理用の関数を取得する.
      (もし取得に失敗した場合は VerifyError)
      ---------------------------------------- -}

      void* verify_func = verify_byte_codes_fn();

      if (verify_func == NULL) {
        jio_snprintf(message, message_len, "Could not link verifier");
        return vmSymbols::java_lang_VerifyError();
      }

  {- -------------------------------------------
  (1) (ResourceMark)
      ---------------------------------------- -}

      ResourceMark rm(THREAD);

  {- -------------------------------------------
  (1) (トレース出力)
      ---------------------------------------- -}

      if (ClassVerifier::_verify_verbose) {
        tty->print_cr("Verifying class %s with old format", klass->external_name());
      }

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      jclass cls = (jclass) JNIHandles::make_local(env, klass->java_mirror());
      jint result;

  {- -------------------------------------------
  (1) 取得した verify 処理用の関数を呼び出して, verification を行う.

      (なお, verify_byte_codes_fn() が返す関数は 2種類ある.
       (VerifyClassCodesForMajorVersion() または VerifyClassCodes())
       どちらが返されたかは _is_new_verify_byte_codes_fn で確認できる (See: verify_byte_codes_fn()).
       種類によって引数が少し異なるので, ここではどちらが返されたかを確認して呼び分けている)
      ---------------------------------------- -}

      {
        HandleMark hm(thread);
        ThreadToNativeFromVM ttn(thread);
        // ThreadToNativeFromVM takes care of changing thread_state, so safepoint
        // code knows that we have left the VM

        if (_is_new_verify_byte_codes_fn) {
          verify_byte_codes_fn_new_t func =
            CAST_TO_FN_PTR(verify_byte_codes_fn_new_t, verify_func);
          result = (*func)(env, cls, message, (int)message_len,
              klass->major_version());
        } else {
          verify_byte_codes_fn_t func =
            CAST_TO_FN_PTR(verify_byte_codes_fn_t, verify_func);
          result = (*func)(env, cls, message, (int)message_len);
        }
      }

  {- -------------------------------------------
  (1) 後片付け
      ---------------------------------------- -}

      JNIHandles::destroy_local(cls);

  {- -------------------------------------------
  (1) verification 結果に応じて結果をリターンする (あるいは例外を発生させる)

      * 返値が 0 の場合は, VerifyError
      * 返値が 1 の場合は, リターンするだけ (verify 成功)
      * 返値が 2 の場合は, OutOfMemoryError
      * 返値が 3 の場合は, ClassFormatError
      * なお, 返値が上記以外というケースはありえない

      (なおコメントによると 
       VerifyClassCodes() は jboolean を返すが, 
       true の場合 (= 1 の場合) に成功, と判定することで互換性を維持している, 
       とのこと)
      ---------------------------------------- -}

      // These numbers are chosen so that VerifyClassCodes interface doesn't need
      // to be changed (still return jboolean (unsigned char)), and result is
      // 1 when verification is passed.
      if (result == 0) {
        return vmSymbols::java_lang_VerifyError();
      } else if (result == 1) {
        return NULL; // verified.
      } else if (result == 2) {
        THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, NULL);
      } else if (result == 3) {
        return vmSymbols::java_lang_ClassFormatError();
      } else {
        ShouldNotReachHere();
        return NULL;
      }
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.