Top


定義場所(file name)

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

説明(description)

// The promoted_flags parameter is used to pass relevant access_flags
// from the methods back up to the containing klass. These flag values
// are added to klass's access_flags.

名前(function name)

objArrayHandle ClassFileParser::parse_methods(constantPoolHandle cp, bool is_interface,
                                              AccessFlags* promoted_flags,
                                              bool* has_final_method,
                                              objArrayOop* methods_annotations_oop,
                                              objArrayOop* methods_parameter_annotations_oop,
                                              objArrayOop* methods_default_annotations_oop,
                                              TRAPS) {

本体部(body)

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

      ClassFileStream* cfs = stream();
      objArrayHandle nullHandle;
      typeArrayHandle method_annotations;
      typeArrayHandle method_parameter_annotations;
      typeArrayHandle method_default_annotations;

  {- -------------------------------------------
  (1) まず, メソッドの個数を読み込む.
      ---------------------------------------- -}

      cfs->guarantee_more(2, CHECK_(nullHandle));  // length
      u2 length = cfs->get_u2_fast();

  {- -------------------------------------------
  (1) 次に, メソッド情報を格納するための objArrayHandle を作成する (これが返値になる).
      (objArrayOop の長さはメソッドの個数)
      (なお, 長さが 0 だった場合はこの時点でリターン)
      ---------------------------------------- -}

      if (length == 0) {
        return objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
      } else {
        objArrayOop m = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
        objArrayHandle methods(THREAD, m);

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

        HandleMark hm(THREAD);
        objArrayHandle methods_annotations;
        objArrayHandle methods_parameter_annotations;
        objArrayHandle methods_default_annotations;

  {- -------------------------------------------
  (1) 次に, メソッドの個数分だけループし, 以下のようにしてメソッド情報の読み込み処理を行う
      ---------------------------------------- -}

        for (int index = 0; index < length; index++) {

    {- -------------------------------------------
  (1.1) ClassFileParser::parse_method() を呼び出して, 実際のパース処理を行う.
        ---------------------------------------- -}

          methodHandle method = parse_method(cp, is_interface,
                                             promoted_flags,
                                             &method_annotations,
                                             &method_parameter_annotations,
                                             &method_default_annotations,
                                             CHECK_(nullHandle));

    {- -------------------------------------------
  (1.1) メソッドが final だった場合には, 
        引数として渡された has_final_method に true を書き込む.
        ---------------------------------------- -}

          if (method->is_final()) {
            *has_final_method = true;
          }

    {- -------------------------------------------
  (1.1) パース結果を返値として返す配列に追加する.
        ---------------------------------------- -}

          methods->obj_at_put(index, method());

    {- -------------------------------------------
  (1.1) メソッド中に annotation があった場合, 
        呼び出し元に伝えるために, その情報を蓄えていく.
        (annotation があったかどうかは, ClassFileParser::parse_method() に渡した 
         method_*_annotations の not_null() メソッドで判定できる)
        (なお, 情報を溜めるために配列が未確保であれば, 
         oopFactory::new_system_objArray() による確保処理も行う)
        ---------------------------------------- -}

          if (method_annotations.not_null()) {
            if (methods_annotations.is_null()) {
              objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
              methods_annotations = objArrayHandle(THREAD, md);
            }
            methods_annotations->obj_at_put(index, method_annotations());
          }
          if (method_parameter_annotations.not_null()) {
            if (methods_parameter_annotations.is_null()) {
              objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
              methods_parameter_annotations = objArrayHandle(THREAD, md);
            }
            methods_parameter_annotations->obj_at_put(index, method_parameter_annotations());
          }
          if (method_default_annotations.not_null()) {
            if (methods_default_annotations.is_null()) {
              objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
              methods_default_annotations = objArrayHandle(THREAD, md);
            }
            methods_default_annotations->obj_at_put(index, method_default_annotations());
          }

  {- -------------------------------------------
  (1) (ここまでで, ClassFileParser::parse_methods() 内のメソッド個数分のループは終了)
      ---------------------------------------- -}

        }

  {- -------------------------------------------
  (1) 次に, メソッドの定義が重複していないかどうかをチェックする. 
      (ただし _need_verify が立っていなければチェックしない)
      重複していたら ClassFormatError にする
      ---------------------------------------- -}

        if (_need_verify && length > 1) {
          // Check duplicated methods
          ResourceMark rm(THREAD);
          NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD(
            THREAD, NameSigHash*, HASH_ROW_SIZE);
          initialize_hashtable(names_and_sigs);
          bool dup = false;
          {
            debug_only(No_Safepoint_Verifier nsv;)
            for (int i = 0; i < length; i++) {
              methodOop m = (methodOop)methods->obj_at(i);
              // If no duplicates, add name/signature in hashtable names_and_sigs.
              if (!put_after_lookup(m->name(), m->signature(), names_and_sigs)) {
                dup = true;
                break;
              }
            }
          }
          if (dup) {
            classfile_parse_error("Duplicate method name&signature in class file %s",
                                  CHECK_(nullHandle));
          }
        }

  {- -------------------------------------------
  (1) 次に, ループ処理で蓄えていた annotation の情報を, 引数で渡されていたポインタに書き込む.
      ---------------------------------------- -}

        *methods_annotations_oop = methods_annotations();
        *methods_parameter_annotations_oop = methods_parameter_annotations();
        *methods_default_annotations_oop = methods_default_annotations();

  {- -------------------------------------------
  (1) パース結果をリターンする.
      ---------------------------------------- -}

        return methods;
      }
    }

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