Top


定義場所(file name)

hotspot/src/share/vm/interpreter/interpreterRuntime.cpp

名前(function name)

void SignatureHandlerLibrary::add(methodHandle method) {

本体部(body)

  {- -------------------------------------------
  (1) (既に signature handler を生成済みであれば 
       (= methodOopDesc::signature_handler() が NULL でない値を返すならば), 
       何もしない)
      ---------------------------------------- -}

      if (method->signature_handler() == NULL) {

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

        // use slow signature handler if we can't do better
        int handler_index = -1;

  {- -------------------------------------------
  (1) (以下で signature handler を生成する.
       作成処理のパスは以下のように何通りか存在する.

       A. UseFastSignatureHandlers オプションが指定されていない場合:
          Interpreter::slow_signature_handler() が指す先のコードで生成.
       B. メソッドの引数の数が多すぎる場合 (Fingerprinter::max_size_of_parameters を超えている場合): 
          Interpreter::slow_signature_handler() で生成.
       C. 上記以外の場合:
          * 同じ型の signature handler を既に作成済みの場合: 
            それを流用する.
          * 〃 未作成の場合:
            InterpreterRuntime::SignatureHandlerGenerator::generate() で作成.
            (ただし, この場合は作成に失敗したら Interpreter::slow_signature_handler() が指す先のコードでの生成にフォールバック))
      ---------------------------------------- -}

  {- -------------------------------------------
  (1) (以下は, 上の "C." のケース)
      ---------------------------------------- -}

        // check if we can use customized (fast) signature handler
        if (UseFastSignatureHandlers && method->size_of_parameters() <= Fingerprinter::max_size_of_parameters) {
          // use customized signature handler
          MutexLocker mu(SignatureHandlerLibrary_lock);

    {- -------------------------------------------
  (1.1) SignatureHandlerLibrary::initialize() を呼んで, 
        (もし SignatureHandlerLibrary の初期化が終わっていなければ) 初期化しておく.
        ---------------------------------------- -}

          // make sure data structure is initialized
          initialize();

    {- -------------------------------------------
  (1.1) メソッドの型情報から fingerprint を作成し, 既に作成済みの signature handler かどうかを調べる.
        ---------------------------------------- -}

          // lookup method signature's fingerprint
          uint64_t fingerprint = Fingerprinter(method).fingerprint();
          handler_index = _fingerprints->find(fingerprint);

    {- -------------------------------------------
  (1.1) まだ作成したことがない signature であれば, 以下の if ブロック内で作成を試みる.
        (逆に, 既に作成済みの signature handler であれば, 
         その結果を流用すればいいので以下の if ブロックの処理は省略)
        ---------------------------------------- -}

          // create handler if necessary
          if (handler_index < 0) {

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

            ResourceMark rm;
            ptrdiff_t align_offset = (address)
              round_to((intptr_t)_buffer, CodeEntryAlignment) - (address)_buffer;
            CodeBuffer buffer((address)(_buffer + align_offset),
                              SignatureHandlerLibrary::buffer_size - align_offset);

      {- -------------------------------------------
  (1.1.1) InterpreterRuntime::SignatureHandlerGenerator::generate() を呼び出して, signature handler の生成を行う.
          ---------------------------------------- -}

            InterpreterRuntime::SignatureHandlerGenerator(method, &buffer).generate(fingerprint);

      {- -------------------------------------------
  (1.1.1) もし signature handler の生成に成功したら, 
          SignatureHandlerLibrary::set_handler() を呼んで内側のバッファにコピーしておく.
          ---------------------------------------- -}

            // copy into code heap
            address handler = set_handler(&buffer);

      {- -------------------------------------------
  (1.1.1) コピーが失敗した場合は, このまま slow signature handler を作る処理へとフォールバック.
          ---------------------------------------- -}

            if (handler == NULL) {
              // use slow signature handler

      {- -------------------------------------------
  (1.1.1) コピーが成功した場合は, 次回以降にも流用するため, 
          生成した signature handler (及び対応する finterprint) を _fingerprints と _handlers 内にメモイズしておく.
          ---------------------------------------- -}

            } else {

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

              // debugging suppport
              if (PrintSignatureHandlers) {
                tty->cr();
                tty->print_cr("argument handler #%d for: %s %s (fingerprint = " UINT64_FORMAT ", %d bytes generated)",
                              _handlers->length(),
                              (method->is_static() ? "static" : "receiver"),
                              method->name_and_sig_as_C_string(),
                              fingerprint,
                              buffer.insts_size());
                Disassembler::decode(handler, handler + buffer.insts_size());
    #ifndef PRODUCT
                tty->print_cr(" --- associated result handler ---");
                address rh_begin = Interpreter::result_handler(method()->result_type());
                address rh_end = rh_begin;
                while (*(int*)rh_end != 0) {
                  rh_end += sizeof(int);
                }
                Disassembler::decode(rh_begin, rh_end);
    #endif
              }

        {- -------------------------------------------
  (1.1.1.1) メモイズ処理
            ---------------------------------------- -}

              // add handler to library
              _fingerprints->append(fingerprint);
              _handlers->append(handler);
              // set handler index
              assert(_fingerprints->length() == _handlers->length(), "sanity check");
              handler_index = _fingerprints->length() - 1;
            }
          }

    {- -------------------------------------------
  (1.1) (以下で実際に signature handler を登録する.
         登録処理は methodOopDesc::set_signature_handler() で行う.
         この処理は SignatureHandlerLibrary_lock によって排他されている.)
        ---------------------------------------- -}

          // Set handler under SignatureHandlerLibrary_lock

    {- -------------------------------------------
  (1.1) この時点で signature handler が作成できていない場合は, 
        Interpreter::slow_signature_handler() が指しているコードで signature handler を作成して登録.
        ---------------------------------------- -}

        if (handler_index < 0) {
          // use generic signature handler
          method->set_signature_handler(Interpreter::slow_signature_handler());

    {- -------------------------------------------
  (1.1) 逆に, signature handler が作成できていれば, その signature handler を登録.
        ---------------------------------------- -}

        } else {
          // set handler
          method->set_signature_handler(_handlers->at(handler_index));
        }

  {- -------------------------------------------
  (1) (以下は, 上の "A." 又は "B." のケース)

      Interpreter::slow_signature_handler() が指しているコードで signature handler を作成して登録する.
      ---------------------------------------- -}

        } else {
          CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
          // use generic signature handler
          method->set_signature_handler(Interpreter::slow_signature_handler());
        }
      }

  {- -------------------------------------------
  (1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
      ---------------------------------------- -}

    #ifdef ASSERT
      int handler_index = -1;
      int fingerprint_index = -2;
      {
        // '_handlers' and '_fingerprints' are 'GrowableArray's and are NOT synchronized
        // in any way if accessed from multiple threads. To avoid races with another
        // thread which may change the arrays in the above, mutex protected block, we
        // have to protect this read access here with the same mutex as well!
        MutexLocker mu(SignatureHandlerLibrary_lock);
        if (_handlers != NULL) {
        handler_index = _handlers->find(method->signature_handler());
        fingerprint_index = _fingerprints->find(Fingerprinter(method).fingerprint());
      }
      }
      assert(method->signature_handler() == Interpreter::slow_signature_handler() ||
             handler_index == fingerprint_index, "sanity check");
    #endif // ASSERT
    }

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