JVM-类型系统的实现
hotspot 的历史
Smalltalk
Smalltalk is an object-oriented, dynamically typed, reflective programming language.
Self
Self was designed mostly by David Ungar and Randall Smith in 1986
They moved to Stanford University and continued work on the language, building the first working Self compiler in 1987
The first public release was in 1990, and the next year the team moved to Sun Microsystems where they continued work on the language.
Self 团队的人去了 Sun Microsystems
Strongtalk
Dave Griswold wanted to use Smalltalk more extensively。
His efforts resulted in the 1993 paper he co-authored with Gilad Bracha. This version was based on adding type-checking to the ParcPlace Systems implementation of Smalltalk; an implementation that started from scratch would gain a better typing system.
1994年 他和 Urs Hölzle, who had finished the second-generation Self compiler (and his Stanford thesis),还有其它几个人一起创建了一家小公司叫 LongView Technologies。这个公司重新实现了 Smalltalk 的运行时环境,并称为 Strongtalk。他们的工作于 1996 年完成。 Sun Microsystems 在 1997 年买下了这有公司(LongView Technologies)。
此后 Self 团队和 LongView Technologies 团队的人都在 Sun 公司进行 Java 的开发
LongView Technologies 团队对 Self 的技术进行了整合形成了最终的 Strongtalk,而后来 Sun Microsystems 就是基于 Strongtalk 进行了 Hotspot 的开发。
创建 JVM
JNI_CreateJavaVM
jni.cpp
1 | _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) { |
create_vm
thread.cpp
下面开始分析 create_vm 各个关键过程
Arguments::process_sun_java_launcher_properties(args);
arguments.cpp
_created_by_gamma_launcher
如果 args 中的 -Dsun.java.launcher= 属性值为 “gamma”, 则将
Arguments::_created_by_gamma_launcher 设置为 true_sun_java_launcher_pid
将 Arguments::_sun_java_launcher_pid 设置成 args k中的sun.java.launcher.pid
os::init
os_windows.cpp 调用系统相关的 API 的获得系统属性,初始化 os 模块的全局变量
1 | // this is called _before_ the global arguments have been parsed |
Arguments::init_system_properties();
初始化系统属性 sysclasspath, java_home, dll_dir
java_home = %JAVA_HOME%
dll_dir = %JAVA_HOME%/bin
Arguments::set_meta_index_path 设置 %JAVA_HOME%/lib/meta-index
Arguments::set_sysclasspath 设置成
1 | static const char classpath_format[] = |
Arguments::parse
解析 args 中的参数
os::init_2
os::init 已经调用过了, os 模块的全局变量已经初始化。
初始化内存相关的属性,
init_globals
init.cpp 进行全局初始化
classLoader_init
加载 verify.dll java.dll zip.dll, 初始化好 bootstrap classpath.
- 加载 %JRE_HOME%/bin/verify.dll
加载 %JRE_HOME%/bin/java.dll
将 java.dll 的句柄保存到 os.cpp 的全局变量 _native_java_library
查找 java.dll 中定义的 Canonicalize 函数,将其保存到 classLoader.cpp 的全局变量 CanonicalizeEntry 中。Canonicalize函数由 JDK 实现,最终编译进 java.dll 中,其实现在 jdk 的 jni_util.c 中。其实功能进行平台相关的路径转换。
ClassLoader 在进行类加载的时候会调用这个 API 进行路径转换。
加载 %JRE_HOME%/bin/zip.dll
ClassLoader::setup_bootstrap_search_path
classLoader.cpp
设置 bootstrap classpath
- 从 Arguments::get_sysclasspath() 获得 sysclasspath
- 拆分 classpath, 使用平台相关的分隔符,windows 上是 “;”, linux 上是 “:”
- 如果拆分后的路径存在,则创建一个 ClassPathEntry 对象。
- 将上面的 ClassPathEntry 添加到 ClassLoader::_first_entry 和 ClassLoader::_last_entry 构成的链表。
ClassLoader::setup_meta_index
解析 %JAVA_HOME%/lib/meta-index 文件,这个文件中存储着 sysclass jar包的索引。
初始化上面创建了的 ClassPathEntry 的链表。