Top


定義場所(file name)

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

名前(function name)

instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {

本体部(body)

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

      ResourceMark rm(THREAD);

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

      EventMark m("loading class " INTPTR_FORMAT, (address)h_name);

  {- -------------------------------------------
  (1) (プロファイル情報の記録) (See: ThreadProfilerMark)
      ---------------------------------------- -}

      ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);

  {- -------------------------------------------
  (1) クラスファイル名を示す文字列を生成する.
      ---------------------------------------- -}

      stringStream st;
      // st.print() uses too much stack space while handling a StackOverflowError
      // st.print("%s.class", h_name->as_utf8());
      st.print_raw(h_name->as_utf8());
      st.print_raw(".class");
      char* name = st.as_string();

  {- -------------------------------------------
  (1) クラスパスを全て調べ (= 登録されている ClassPathEntry オブジェクトを全て辿り), 
      指定のクラスファイルを含むものを見つけて, 
      そのクラスファイルを読むためのファイルストリームを生成する.

      結果は stream 局所変数に格納される. 
      (なお, 見つからなければ stream は NULL のままになる)
      ---------------------------------------- -}

      // Lookup stream for parsing .class file
      ClassFileStream* stream = NULL;
      int classpath_index = 0;
      {
        PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
                                   ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
                                   PerfClassTraceTime::CLASS_LOAD);
        ClassPathEntry* e = _first_entry;
        while (e != NULL) {
          stream = e->open_stream(name);
          if (stream != NULL) {
            break;
          }
          e = e->next();
          ++classpath_index;
        }
      }

  {- -------------------------------------------
  (1) ClassFileParser::parseClassFile() を呼んで, クラスファイルの内容をパースする.
      (また, パース後には ClassLoader::add_package() でパッケージ情報も登録している)

      (ただし, クラスファイルが見つからなかった場合 (stream が NULL の場合) は,
      処理しようがないので, 以上の処理は行わない)
      ---------------------------------------- -}

      instanceKlassHandle h(THREAD, klassOop(NULL));
      if (stream != NULL) {

        // class file found, parse it
        ClassFileParser parser(stream);
        Handle class_loader;
        Handle protection_domain;
        TempNewSymbol parsed_name = NULL;
        instanceKlassHandle result = parser.parseClassFile(h_name,
                                                           class_loader,
                                                           protection_domain,
                                                           parsed_name,
                                                           false,
                                                           CHECK_(h));

        // add to package table
        if (add_package(name, classpath_index, THREAD)) {
          h = result;
        }
      }

  {- -------------------------------------------
  (1) 結果をリターン
      ---------------------------------------- -}

      return h;
    }

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