Top


定義場所(file name)

hotspot/src/share/vm/oops/cpCacheOop.cpp

説明(description)

(各フィールドの内容については ConstantPoolCacheEntry クラスの説明参照)

名前(function name)

void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
                                        methodHandle method,
                                        int vtable_index) {

本体部(body)

  {- -------------------------------------------
  (1) (assert)
      ---------------------------------------- -}

      assert(!is_secondary_entry(), "");
      assert(method->interpreter_entry() != NULL, "should have been set at this point");
      assert(!method->is_obsolete(),  "attempt to write obsolete method to cpCache");

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

      bool change_to_virtual = (invoke_code == Bytecodes::_invokeinterface);

      int byte_no = -1;
      bool needs_vfinal_flag = false;

  {- -------------------------------------------
  (1) _f1 及び _f2 を設定
      ---------------------------------------- -}

      switch (invoke_code) {
        case Bytecodes::_invokevirtual:
        case Bytecodes::_invokeinterface: {
            if (method->can_be_statically_bound()) {
              set_f2((intptr_t)method());
              needs_vfinal_flag = true;
            } else {
              assert(vtable_index >= 0, "valid index");
              set_f2(vtable_index);
            }
            byte_no = 2;
            break;
        }

        case Bytecodes::_invokedynamic:  // similar to _invokevirtual
          if (TraceInvokeDynamic) {
            tty->print_cr("InvokeDynamic set_method%s method="PTR_FORMAT" index=%d",
                          (is_secondary_entry() ? " secondary" : ""),
                          (intptr_t)method(), vtable_index);
            method->print();
            this->print(tty, 0);
          }
          assert(method->can_be_statically_bound(), "must be a MH invoker method");
          assert(_f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized");
          // SystemDictionary::find_method_handle_invoke only caches
          // methods which signature classes are on the boot classpath,
          // otherwise the newly created method is returned.  To avoid
          // races in that case we store the first one coming in into the
          // cp-cache atomically if it's still unset.
          set_f1_if_null_atomic(method());
          needs_vfinal_flag = false;  // _f2 is not an oop
          assert(!is_vfinal(), "f2 not an oop");
          byte_no = 1;  // coordinate this with bytecode_number & is_resolved
          break;

        case Bytecodes::_invokespecial:
          // Preserve the value of the vfinal flag on invokevirtual bytecode
          // which may be shared with this constant pool cache entry.
          needs_vfinal_flag = is_resolved(Bytecodes::_invokevirtual) && is_vfinal();
          // fall through
        case Bytecodes::_invokestatic:
          set_f1(method());
          byte_no = 1;
          break;
        default:
          ShouldNotReachHere();
          break;
      }

  {- -------------------------------------------
  (1) _flags を設定 (型情報, 等)
      ---------------------------------------- -}

      set_flags(as_flags(as_TosState(method->result_type()),
                         method->is_final_method(),
                         needs_vfinal_flag,
                         false,
                         change_to_virtual,
                         true)|
                method()->size_of_parameters());

  {- -------------------------------------------
  (1) _indices を設定
      (_indices は set_bytecode_1(), set_bytecode_2() で設定)
      ---------------------------------------- -}

      // Note:  byte_no also appears in TemplateTable::resolve.
      if (byte_no == 1) {
        set_bytecode_1(invoke_code);
      } else if (byte_no == 2)  {
        if (change_to_virtual) {
          // NOTE: THIS IS A HACK - BE VERY CAREFUL!!!
          //
          // Workaround for the case where we encounter an invokeinterface, but we
          // should really have an _invokevirtual since the resolved method is a
          // virtual method in java.lang.Object. This is a corner case in the spec
          // but is presumably legal. javac does not generate this code.
          //
          // We set bytecode_1() to _invokeinterface, because that is the
          // bytecode # used by the interpreter to see if it is resolved.
          // We set bytecode_2() to _invokevirtual.
          // See also interpreterRuntime.cpp. (8/25/2000)
          // Only set resolved for the invokeinterface case if method is public.
          // Otherwise, the method needs to be reresolved with caller for each
          // interface call.
          if (method->is_public()) set_bytecode_1(invoke_code);
          set_bytecode_2(Bytecodes::_invokevirtual);
        } else {
          set_bytecode_2(invoke_code);
        }
      } else {
        ShouldNotReachHere();
      }

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

      NOT_PRODUCT(verify(tty));
    }

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