android art jni,Android虚拟机art流程:JNI_CreateJavaVM 对运行时 classlinker的建立

本文详细探讨了Android运行时ClassLinker的初始化过程,从Runtime::Init开始,涉及ClassLinker构造函数、InitFromBootImage方法。在InitFromBootImage中,主要任务包括注册OAT文件,初始化基本类,如String、Class等,并设置相关指针。这个过程对于理解Android系统的类加载机制至关重要。
摘要由CSDN通过智能技术生成

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值