Top


定義場所(file name)

hotspot/src/share/vm/runtime/thread.cpp

説明(description)

// Find a command line agent library and return its entry point for
//         -agentlib:  -agentpath:   -Xrun
// num_symbol_entries must be passed-in since only the caller knows the number of symbols in the array.

名前(function name)

static OnLoadEntry_t lookup_on_load(AgentLibrary* agent, const char *on_load_symbols[], size_t num_symbol_entries) {

本体部(body)

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

      OnLoadEntry_t on_load_entry = NULL;
      void *library = agent->os_lib();  // check if we have looked it up before

  {- -------------------------------------------
  (1) agent 引数で指定された AgentLibrary が
      まだ対応するライブラリをロードしていない状態であれば, 
      os::dll_load() でロードしておく.
      ---------------------------------------- -}

      if (library == NULL) {
        char buffer[JVM_MAXPATHLEN];
        char ebuf[1024];
        const char *name = agent->name();
        const char *msg = "Could not find agent library ";

        if (agent->is_absolute_path()) {
          library = os::dll_load(name, ebuf, sizeof ebuf);
          if (library == NULL) {
            const char *sub_msg = " in absolute path, with error: ";
            size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
            char *buf = NEW_C_HEAP_ARRAY(char, len);
            jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
            // If we can't find the agent, exit.
            vm_exit_during_initialization(buf, NULL);
            FREE_C_HEAP_ARRAY(char, buf);
          }
        } else {
          // Try to load the agent from the standard dll directory
          os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), name);
          library = os::dll_load(buffer, ebuf, sizeof ebuf);
    #ifdef KERNEL
          // Download instrument dll
          if (library == NULL && strcmp(name, "instrument") == 0) {
            char *props = Arguments::get_kernel_properties();
            char *home  = Arguments::get_java_home();
            const char *fmt   = "%s/bin/java %s -Dkernel.background.download=false"
                          " sun.jkernel.DownloadManager -download client_jvm";
            size_t length = strlen(props) + strlen(home) + strlen(fmt) + 1;
            char *cmd = NEW_C_HEAP_ARRAY(char, length);
            jio_snprintf(cmd, length, fmt, home, props);
            int status = os::fork_and_exec(cmd);
            FreeHeap(props);
            if (status == -1) {
              warning(cmd);
              vm_exit_during_initialization("fork_and_exec failed: %s",
                                             strerror(errno));
            }
            FREE_C_HEAP_ARRAY(char, cmd);
            // when this comes back the instrument.dll should be where it belongs.
            library = os::dll_load(buffer, ebuf, sizeof ebuf);
          }
    #endif // KERNEL
          if (library == NULL) { // Try the local directory
            char ns[1] = {0};
            os::dll_build_name(buffer, sizeof(buffer), ns, name);
            library = os::dll_load(buffer, ebuf, sizeof ebuf);
            if (library == NULL) {
              const char *sub_msg = " on the library path, with error: ";
              size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
              char *buf = NEW_C_HEAP_ARRAY(char, len);
              jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
              // If we can't find the agent, exit.
              vm_exit_during_initialization(buf, NULL);
              FREE_C_HEAP_ARRAY(char, buf);
            }
          }
        }
        agent->set_os_lib(library);
      }

  {- -------------------------------------------
  (1) os::dll_lookup() を呼んで, 
      on_load_symbols 引数で指定された関数名のエントリポイントの位置を探す.

      なお, on_load_symbols 引数は配列になっており, 複数の候補を指定できる.
      候補を前から順に探していき, 最初に見つかった時点で break してループを抜ける.
      ---------------------------------------- -}

      // Find the OnLoad function.
      for (size_t symbol_index = 0; symbol_index < num_symbol_entries; symbol_index++) {
        on_load_entry = CAST_TO_FN_PTR(OnLoadEntry_t, os::dll_lookup(library, on_load_symbols[symbol_index]));
        if (on_load_entry != NULL) break;
      }

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

      return on_load_entry;
    }

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