Overview
-
source
- art/runtime/gc/space/image_space.h
- art/runtime/gc/space/image_space.cc
-
数据结构
- ImageSpace
- ImageSpaceLoader
- OatFile
- VdexFile
- OatDexFile
ImageSpace的加载
流程
LoadBootImage()
BootImage是虚拟机启动时,在Heap初始化阶段加载的.
-
Runtime::Init()
- gc::Heap::Heap()
- ImageSpace::LoadBootImage()
- ImageSpace::CreateBootImage()
- ImageSpace::ExtractMultiImageLocations()
- ImageSpace::LoadBootImage()
- gc::Heap::Heap()
-
ImageSpace::CreateBootImage()
- MarkZygoteStart()
- FindImageFilenameImpl()
- 判断
- found_image && has_system && has_cache
- 若ChecksumsMatch()匹配,则会Load
- ImageSpaceLoader::Load()
- 若ChecksumsMatch()匹配,则会Load
- found_image && !has_system && has_cache
- ImageSpaceLoader::Load()
- found_image && has_system && !relocate
- 此分支应该进不来.
- relocate默认是需要的
bool ShouldRelocate() const { return must_relocate_ && CanRelocate(); } - must_relocate_为true static constexpr bool kDefaultMustRelocate = true RUNTIME_OPTIONS_KEY (bool, Relocate, kDefaultMustRelocate) - CanRelocate()为true bool Runtime::CanRelocate() const { return !IsAotCompiler() || compiler_callbacks_->IsRelocationPossible(); }
- ImageSpaceLoader::Load()
- found_image && has_system && relocate
- RelocateImage()
- ImageSpaceLoader::Load()
- !has_system
- GenerateImage()
- ImageSpaceLoader::Load()
- found_image && has_system && has_cache
-
space::ImageSpace::ExtractMultiImageLocations()
- 使用":"分割bootclasspath字符串
- 获取input_image_file_nameiamge[0]的common suffix,即 "boot.art"
- 从images[1]开始,将/system/framework/xxx.art存储image_file_names
- 后面ImageSpace::LoadBootImage()会在for()执行多次CreateBootImage()
-
RelocateImage()
- ChooseRelocationOffsetDelta()
- patchoat
-
GenerateImage()
- ChooseRelocationOffsetDelta()
- dex2oat
ImageSpaceLoader::Load()
-
ImageSpaceLoader::Load()
- ImageSpaceLoader::Init()
-
ImageSpaceLoader::Init()
OS::OpenFileForReading(image_filename))
-
LoadImageFile(): 加载art文件
- MemMap::MapFileAtAddress()
- MemMap::MapInternal()
- mmap()
- MemMap::MapInternal()
- 映射文件大小为image_size_, 只包括ImageHeader+data, 不包括padding + bitmap部分.
- MemMap::MapFileAtAddress()
image_bitmap_map(MemMap::MapFileAtAddress())
RelocateInPlace()
space(new ImageSpace())
-
ImageSpaceLoader::OpenOatFile()
- oat_file(OatFile::Open())
- OatFileBase::OpenOatFile<>
-
new kOatFileBaseSubType()
- new DlOpenOatFile()
- new ElfOatFile()
-
LoadVdex(): 加载VdexFile文件
- OatFileBase::LoadVdex()
-
PreLoad()
- DlOpenOatFile::PreLoad()
- ElfOatFile::PreLoad()
-
Load(): 加载OatFile文件
- DlOpenOatFile::Load()->DlOpenOatFile::Dlopen()->android_dlopen_ext()
- ElfOatFile::ElfFileOpen()
- ElfFile::Open()
- ElfFile::Load()
-
OatFileBase::ComputeFields()
- begin_ = FindDynamicSymbolAddress("oatdata")
- end_ = FindDynamicSymbolAddress("oatlastword")
- end_ += sizeof(uint32_t)
- bss_begin_ = FindDynamicSymbolAddress("oatbss")
- bss_end_ += sizeof(uint32_t)
- bss_roots_ = FindDynamicSymbolAddress("oatbssroots")
-
PreSetup()
- DlOpenOatFile::PreSetup()
- ElfOatFile::PreSetup() 空
-
Setup()
- OatFileBase::Setup()
- OatDexFile* oat_dex_file = new OatDexFile()
- TypeLookupTable::Open()
- oat_dex_files_.Put(key, oat_dex_file)
- OatDexFile* oat_dex_file = new OatDexFile()
- OatFileBase::Setup()
space->ValidateOatFile()
-
- OatFileBase::OpenOatFile<>
- oat_file(OatFile::Open())
space->oat_file_non_owned_ = space->oat_file_.get()
实验
- boot_image_spaces_内容
elem[0 ] = {ImageSpace* = 0x74da427600, OatFile* = 0x74da4fb2c0, begin_ = 0x6fb4a000, name = /data/dalvik-cache/arm64/system@framework@boot.art}
elem[1 ] = {ImageSpace* = 0x74da427680, OatFile* = 0x74da4cb140, begin_ = 0x6fdf1000, name = /data/dalvik-cache/arm64/system@framework@boot-core-libart.art}
elem[2 ] = {ImageSpace* = 0x74da427700, OatFile* = 0x74da4cb000, begin_ = 0x6fef7000, name = /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art}
elem[3 ] = {ImageSpace* = 0x74da427780, OatFile* = 0x74da4cb280, begin_ = 0x6ff41000, name = /data/dalvik-cache/arm64/system@framework@boot-okhttp.art}
elem[4 ] = {ImageSpace* = 0x74da427800, OatFile* = 0x74da4cb3c0, begin_ = 0x6ff77000, name = /data/dalvik-cache/arm64/system@framework@boot-legacy-test.art}
elem[5 ] = {ImageSpace* = 0x74da427880, OatFile* = 0x74da4cb500, begin_ = 0x6ff7b000, name = /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art}
elem[6 ] = {ImageSpace* = 0x74da427900, OatFile* = 0x74da4cb640, begin_ = 0x6ffbe000, name = /data/dalvik-cache/arm64/system@framework@boot-ext.art}
elem[7 ] = {ImageSpace* = 0x74da427980, OatFile* = 0x74da4cb780, begin_ = 0x6fff9000, name = /data/dalvik-cache/arm64/system@framework@boot-framework.art}
elem[8 ] = {ImageSpace* = 0x74da427a00, OatFile* = 0x74da4cb8c0, begin_ = 0x70786000, name = /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art}
elem[9 ] = {ImageSpace* = 0x74da427b00, OatFile* = 0x74da4cba00, begin_ = 0x707f2000, name = /data/dalvik-cache/arm64/system@framework@boot-voip-common.art}
elem[10] = {ImageSpace* = 0x74da427b80, OatFile* = 0x74da4cbb40, begin_ = 0x707fb000, name = /data/dalvik-cache/arm64/system@framework@boot-ims-common.art}
elem[11] = {ImageSpace* = 0x74da427c00, OatFile* = 0x74da4cbc80, begin_ = 0x70803000, name = /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art}
elem[12] = {ImageSpace* = 0x74da427c80, OatFile* = 0x74da4cbdc0, begin_ = 0x70827000, name = /data/dalvik-cache/arm64/system@framework@boot-org.apache.http.legacy.boot.art}
elem[13] = {ImageSpace* = 0x74da427d00, OatFile* = 0x74da4cbf00, begin_ = 0x7084f000, name = /data/dalvik-cache/arm64/system@framework@boot-android.hidl.base-V1.0-java.art}
elem[14] = {ImageSpace* = 0x74da427d80, OatFile* = 0x74da4cc040, begin_ = 0x70850000, name = /data/dalvik-cache/arm64/system@framework@boot-android.hidl.manager-V1.0-java.art}
- 第一个ImageSpace
$39 = (art::gc::space::ImageSpace) {
<art::gc::space::MemMapSpace> = {
<art::gc::space::ContinuousSpace> = {
<art::gc::space::Space> = {
_vptr$Space = 0x74da3df070 <vtable for art::gc::space::ImageSpace+16>,
name_ = {
<std::__1::__basic_string_common<true>> = {<No data fields>},
members of std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >:
__r_ = {
<std::__1::__libcpp_compressed_pair_imp<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__rep, std::__1::allocator<char>, 2>> = {
<std::__1::allocator<char>> = {<No data fields>},
members of std::__1::__libcpp_compressed_pair_imp<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__rep, std::__1::allocator<char>, 2>:
__first_ = {
{
__l = {
__cap_ = 0x41,
__size_ = 0x32,
__data_ = 0x74da4f59c0
},
__s = {
{
__size_ = 0x41,
__lx = 0x41
},
__data_ = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x59, 0x4f, 0xda, 0x74, 0x0, 0x0, 0x0}
},
__r = {
__words = {0x41, 0x32, 0x74da4f59c0}
}
}
}
}, <No data fields>},
static npos = 0xffffffffffffffff
},
gc_retention_policy_ = 0x0
},
members of art::gc::space::ContinuousSpace:
begin_ = 0x6fb4a000,
end_ = {
<std::__1::atomic<unsigned char*>> = {
<std::__1::__atomic_base<unsigned char*, false>> = {
__a_ = 0x6fc49940
}, <No data fields>}, <No data fields>},
limit_ = 0x6fc49940
},
members of art::gc::space::MemMapSpace:
mem_map_ = {
__ptr_ = {
<std::__1::__libcpp_compressed_pair_imp<art::MemMap*, std::__1::default_delete<art::MemMap>, 2>> = {
<std::__1::default_delete<art::MemMap>> = {<No data fields>},
members of std::__1::__libcpp_compressed_pair_imp<art::MemMap*, std::__1::default_delete<art::MemMap>, 2>:
__first_ = 0x74da4e6e20
}, <No data fields>}
}
},
members of art::gc::space::ImageSpace:
static bitmap_index_ = {
<std::__1::atomic<unsigned int>> = {
<std::__1::__atomic_base<unsigned int, true>> = {
<std::__1::__atomic_base<unsigned int, false>> = {
__a_ = 0x10
}, <No data fields>}, <No data fields>}, <No data fields>},
live_bitmap_ = {
__ptr_ = {
<std::__1::__libcpp_compressed_pair_imp<art::gc::accounting::SpaceBitmap<8>*, std::__1::default_delete<art::gc::accounting::SpaceBitmap<8> >, 2>> = {
<std::__1::default_delete<art::gc::accounting::SpaceBitmap<8> >> = {<No data fields>},
members of std::__1::__libcpp_compressed_pair_imp<art::gc::accounting::SpaceBitmap<8>*, std::__1::default_delete<art::gc::accounting::SpaceBitmap<8> >, 2>:
__first_ = 0x74da4f5880
}, <No data fields>}
},
oat_file_ = {
__ptr_ = {
<std::__1::__libcpp_compressed_pair_imp<art::OatFile*, std::__1::default_delete<art::OatFile>, 2>> = {
<std::__1::default_delete<art::OatFile>> = {<No data fields>},
members of std::__1::__libcpp_compressed_pair_imp<art::OatFile*, std::__1::default_delete<art::OatFile>, 2>:
__first_ = 0x0
}, <No data fields>}
},
oat_file_non_owned_ = 0x74da4fb2c0,
image_location_ = {
<std::__1::__basic_string_common<true>> = {<No data fields>},
members of std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >:
__r_ = {
<std::__1::__libcpp_compressed_pair_imp<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__rep, std::__1::allocator<char>, 2>> = {
<std::__1::allocator<char>> = {<No data fields>},
members of std::__1::__libcpp_compressed_pair_imp<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__rep, std::__1::allocator<char>, 2>:
__first_ = {
{
__l = {
__cap_ = 0x21,
__size_ = 0x1a,
__data_ = 0x74da4d0780
},
__s = {
{
__size_ = 0x21,
__lx = 0x21
},
__data_ = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x7, 0x4d, 0xda, 0x74, 0x0, 0x0, 0x0}
},
__r = {
__words = {0x21, 0x1a, 0x74da4d0780}
}
}
}
}, <No data fields>},
static npos = 0xffffffffffffffff
}
}
(gdb) x/1sb 0x74da4d0780
0x74da4d0780: "/system/framework/boot.art"
(gdb) x/1sb 0x74da4f59c0
0x74da4f59c0: "/data/dalvik-cache/arm64/system@framework@boot.art"
boot.art的maps文件
6fb4a000-6fdf1000 rw-p 00000000 fd:00 278018 /data/dalvik-cache/arm64/system@framework@boot.art
... ...
74deb2c000-74deb30000 r--p 002a7000 fd:00 278018 /data/dalvik-cache/arm64/system@framework@boot.art