《jdk8u源码分析》10.AddApplicationOptions

src/share/bin/java.c::AddApplicationOptions

/*
 * For our tools, we try to add 3 VM options:
 *      -Denv.class.path=<envcp>
 *      -Dapplication.home=<apphome>
 *      -Djava.class.path=<appcp>
 * <envcp>   is the user's setting of CLASSPATH -- for instance the user
 *           tells javac where to find binary classes through this environment
 *           variable.  Notice that users will be able to compile against our
 *           tools classes (sun.tools.javac.Main) only if they explicitly add
 *           tools.jar to CLASSPATH.
 * <apphome> is the directory where the application is installed.
 * <appcp>   is the classpath to where our apps' classfiles are.
 */
static jboolean
AddApplicationOptions(int cpathc, const char **cpathv)
{
    char *envcp, *appcp, *apphome;
    char home[MAXPATHLEN]; /* application home */
    char separator[] = { PATH_SEPARATOR, '\0' };
    int size, i;

	//获取环境变量中的CLASSPATH配置,展开通配符
    {
        const char *s = getenv("CLASSPATH");
        if (s) {
        	//@see: 9.1.JLI_WildcardExpandClasspath
            s = (char *) JLI_WildcardExpandClasspath(s);
            /* 40 for -Denv.class.path= */
            //增加可选参数:-Denv.class.path=
            if (JLI_StrLen(s) + 40 > JLI_StrLen(s)) { // Safeguard from overflow
                envcp = (char *)JLI_MemAlloc(JLI_StrLen(s) + 40);
                sprintf(envcp, "-Denv.class.path=%s", s);
                AddOption(envcp, NULL);
            }
        }
    }

	//@see: 6.1.GetJREPath
    if (!GetApplicationHome(home, sizeof(home))) {
    	//"Error: Could not determine application home."
        JLI_ReportErrorMessage(CFG_ERROR5);
        return JNI_FALSE;
    }

    /* 40 for '-Dapplication.home=' */
    //增加可选参数:-Dapplication.home=
    apphome = (char *)JLI_MemAlloc(JLI_StrLen(home) + 40);
    sprintf(apphome, "-Dapplication.home=%s", home);
    AddOption(apphome, NULL);
	
	//依据宏定义变量JAVA_ARGS是否存在给const_jargs赋初值
    //增加可选参数:-Djava.class.path=
    /* How big is the application's classpath? */
    size = 40;                                 /* 40: "-Djava.class.path=" */
    for (i = 0; i < cpathc; i++) {
        size += (int)JLI_StrLen(home) + (int)JLI_StrLen(cpathv[i]) + 1; /* 1: separator */
    }
    appcp = (char *)JLI_MemAlloc(size + 1);
    JLI_StrCpy(appcp, "-Djava.class.path=");
    for (i = 0; i < cpathc; i++) {
        JLI_StrCat(appcp, home);                        /* c:\program files\myapp */
        JLI_StrCat(appcp, cpathv[i]);           /* \lib\myapp.jar         */
        JLI_StrCat(appcp, separator);           /* ;                      */
    }
    appcp[JLI_StrLen(appcp)-1] = '\0';  /* remove trailing path separator */
    AddOption(appcp, NULL);
    return JNI_TRUE;
}

src/share/bin/defines.h::APP_CLASSPATH::PROGNAME

#ifdef JAVA_ARGS
static const char* const_progname = "java";
static const char* const_jargs[] = JAVA_ARGS;
/*
 * ApplicationHome is prepended to each of these entries; the resulting
 * strings are concatenated (separated by PATH_SEPARATOR) and used as the
 * value of -cp option to the launcher.
 */
#ifndef APP_CLASSPATH
#define APP_CLASSPATH        { "/lib/tools.jar", "/classes" }	//默认值
#endif /* APP_CLASSPATH */
static const char* const_appclasspath[] = APP_CLASSPATH;
#else  /* !JAVA_ARGS */
#ifdef PROGNAME
static const char* const_progname = PROGNAME;
#else
static char* const_progname = NULL;
#endif
static const char** const_jargs = NULL;
static const char** const_appclasspath = NULL;
#endif /* JAVA_ARGS */

src/share/bin/java.c::AddOption

/*
 * Adds a new VM option with the given given name and value.
 */
void
AddOption(char *str, void *info)
{
    /*
     * Expand options array if needed to accommodate at least one more
     * VM option.
     */
    //JavaVMOption扩容,默认最大可选项4个,每次扩容容量扩大一倍
    if (numOptions >= maxOptions) {
        if (options == 0) {
            maxOptions = 4;
            options = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption));
        } else {
            JavaVMOption *tmp;
            maxOptions *= 2;
            tmp = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption));
            memcpy(tmp, options, numOptions * sizeof(JavaVMOption));
            JLI_MemFree(options);
            options = tmp;
        }
    }
    options[numOptions].optionString = str;
    options[numOptions++].extraInfo = info;

	//如果添加线程栈大小配置,将参数值(容量)转换为字节
    if (JLI_StrCCmp(str, "-Xss") == 0) {
        jlong tmp;
        if (parse_size(str + 4, &tmp)) {
            threadStackSize = tmp;
        }
    }

	//如果添加最大堆内存配置,将参数值(容量)转换为字节
    if (JLI_StrCCmp(str, "-Xmx") == 0) {
        jlong tmp;
        if (parse_size(str + 4, &tmp)) {
            maxHeapSize = tmp;
        }
    }

	//如果添加最小堆内存配置,将参数值(容量)转换为字节
    if (JLI_StrCCmp(str, "-Xms") == 0) {
        jlong tmp;
        if (parse_size(str + 4, &tmp)) {
           initialHeapSize = tmp;
        }
    }
}

src/share/bin/java.c

/*
 * List of VM options to be specified when the VM is created.
 */
static JavaVMOption *options;
static int numOptions, maxOptions;//当前options容量 最大options容量

src/share/javavm/export/jni.h::JavaVMOption

typedef struct JavaVMOption {
    char *optionString;
    void *extraInfo;
} JavaVMOption;

src/share/bin/java.c::parse_size

/* copied from HotSpot function "atomll()" */
static int
parse_size(const char *s, jlong *result) {
  jlong n = 0;
  //读取一个连续的64位整形数字,返回成功匹配和赋值的个数
  //如:-Xmx81920k,n=81920
  
  //strcpy( dtm, "Saturday March 25 1989" );
  //sscanf( dtm, "%s %s %d  %d", weekday, month, &day, &year );
  //printf("%s %d, %d = %s\n", month, day, year, weekday );
  //输出:March 25, 1989 = Saturday
  int args_read = sscanf(s, jlong_format_specifier(), &n);
  if (args_read != 1) {
    return 0;
  }
  while (*s != '\0' && *s >= '0' && *s <= '9') {
    s++;
  }
  // 4705540: illegal if more characters are found after the first non-digit
  //保证数字后面有且仅有1个非数字字符
  if (JLI_StrLen(s) > 1) {
    return 0;
  }
  //单位换算为字节(byte)
  switch (*s) {
    case 'T': case 't':
      *result = n * GB * KB;
      return 1;
    case 'G': case 'g':
      *result = n * GB;
      return 1;
    case 'M': case 'm':
      *result = n * MB;
      return 1;
    case 'K': case 'k':
      *result = n * KB;
      return 1;
    case '\0':
      *result = n;
      return 1;
    default:
      /* Create JVM with default stack and let VM handle malformed -Xss string*/
      return 0;
  }
}

src/windows/bin/java_md.c::jlong_format_specifier

const char *
jlong_format_specifier() {
	//64未整形
	//@see: https://www.byvoid.com/zhs/blog/c-int64
    return "%I64d";
}

src/share/bin/java.h::KB::MB::GB

# define KB (1024UL)
# define MB (1024UL * KB)
# define GB (1024UL * MB)

猜你喜欢

转载自blog.csdn.net/weixin_37477523/article/details/88364281