startVm————》JNI_CreateJavaVM---》Runtime::Create---》Runtime::Init
classlinker的建立
bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
...
intern_table_ = new InternTable;
class_linker_ = new ClassLinker(intern_table_);
if (GetHeap()->HasBootImageSpace()) {
std::string error_msg;
bool result = class_linker_->InitFromBootImage(&error_msg);
....
...
}
还是从Runtime::Init开始。在前面中我们分析了oat文件的加载,涉及到space空间的建立的部分没有讲的很细。总之在heap的建立过程中,关注oat文件的加载,和镜像空间的建立认真看。现在我们来看下ClassLinker的建立。
ClassLinker::ClassLinker(InternTable* intern_table)
// dex_lock_ is recursive as it may be used in stack dumping.
: dex_lock_("ClassLinker dex lock", kDefaultMutexLevel),
...
intern_table_(intern_table),
quick_resolution_trampoline_(nullptr),
quick_imt_conflict_trampoline_(nullptr),
quick_generic_jni_trampoline_(nullptr),
quick_to_interpreter_bridge_trampoline_(nullptr),
image_pointer_size_(sizeof(void*)) {
CHECK(intern_table_ != nullptr);
static_assert(kFindArrayCacheSize == arraysize(find_array_class_cache_),
"Array cache size wrong.");
std::fill_n(find_array_class_cache_, kFindArrayCacheSize, GcRoot<:class>(nullptr));
}
构造函数并没有做太多事情。
if (GetHeap()->HasBootImageSpace()) {
std::string error_msg;
bool result = class_linker_->InitFromBootImage(&error_msg);
这个heap是上篇文章讲的,所以肯定有的。我们看下InitFromBootImage。会做什么事情。
bool ClassLinker::InitFromBootImage(std::string* error_msg) {
VLOG(startup) << __FUNCTION__ << " entering";
CHECK(!init_done_);
Runtime* const runtime = Runtime::Current();
Thread* const self = Thread::Current();
gc::Heap* const heap = runtime->GetHeap();
std::vector<:space::imagespace> spaces = heap->GetBootImageSpaces();
CHECK(!spaces.empty());
image_pointer_size_ = spaces[0]->GetImageHeader().GetPointerSize();
if (!ValidPointerSize(image_pointer_size_)) {
*error_msg = StringPrintf("Invalid image pointer size: %zu", image_pointer_size_);
return false;
}
dex_cache_boot_image_class_lookup_required_ = true;
std::vector oat_files =
runtime->GetOatFileManager().RegisterImageOatFiles(spaces);
const OatHeader& default_oat_header = oat_files[0]->GetOatHeader();
CHECK_EQ(default_oat_header.GetImageFileLocationOatChecksum(), 0U);
CHECK_EQ(default_oat_header.GetImageFileLocationOatDataBegin(), 0U);
const char* image_file_location = oat_files[0]->GetOatHeader().
GetStoreValueByKey(OatHeader::kImageLocationKey);
CHECK(image_file_location == nullptr || *image_file_location == 0);
quick_resolution_trampoline_ = default_oat_header.GetQuickResolutionTrampoline();
quick_imt_conflict_trampoline_ = default_oat_header.GetQuickImtConflictTrampoline();
quick_generic_jni_trampoline_ = default_oat_header.GetQuickGenericJniTrampoline();
quick_to_interpreter_bridge_trampoline_ = default_oat_header.GetQuickToInterpreterBridge();
class_roots_ = GcRoot<:objectarray>>(
down_cast<:objectarray>*>(
spaces[0]->GetImageHeader().GetImageRoot(ImageHeader::kClassRoots)));
mirror::Class::SetClassClass(class_roots_.Read()->Get(kJavaLangClass));
mirror::String::SetClass(GetClassRoot(kJavaLangString));
mirror::Field::SetClass(GetClassRoot(kJavaLangReflectField));
mirror::Field::SetArrayClass(GetClassRoot(kJavaLangReflectFieldArrayClass));
mirror::Constructor::SetClass(GetClassRoot(kJavaLangReflectConstructor));
mirror::Constructor::SetArrayClass(GetClassRoot(kJavaLangReflectConstructorArrayClass));
mirror::Method::SetClass(GetClassRoot(kJavaLangReflectMethod));
mirror::Method::SetArrayClass(GetClassRoot(kJavaLangReflectMethodArrayClass));
mirror::Reference::SetClass(GetClassRoot(kJavaLangRefReference));
mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
mirror::ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
mirror::CharArray::SetArrayClass(GetClassRoot(kCharArrayClass));
mirror::DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
mirror::FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
mirror::IntArray::SetArrayClass(GetClassRoot(kIntArrayClass));
mirror::LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
mirror::ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
mirror::Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
mirror::StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
for (gc::space::ImageSpace* image_space : spaces) {
// Boot class loader, use a null handle.
std::vector<:unique_ptr dexfile>> dex_files;
if (!AddImageSpace(image_space,
ScopedNullHandle<:classloader>(),
/*dex_elements*/nullptr,
/*dex_location*/nullptr,
/*out*/&dex_files,
error_msg)) {
return false;
}
boot_dex_files_.insert(boot_dex_files_.end(),
std::make_move_iterator(dex_files.begin()),
std::make_move_iterator(dex_files.end()));
}
return true;
}
这里面做了几件事情:
把oatfile注册到otamanager中
mirror了好多基础类,虽然不知道这样做的是干什么的。
addImageSpace