ImageSpace

Overview

  • source

    • art/runtime/gc/space/image_space.h
    • art/runtime/gc/space/image_space.cc
  • 数据结构

    • ImageSpace
    • ImageSpaceLoader
    • OatFile
    • VdexFile
    • OatDexFile

ImageSpace的加载

流程

ImageSpace.png

LoadBootImage()

BootImage是虚拟机启动时,在Heap初始化阶段加载的.

  • Runtime::Init()

    • gc::Heap::Heap()
      • ImageSpace::LoadBootImage()
        • ImageSpace::CreateBootImage()
        • ImageSpace::ExtractMultiImageLocations()
  • ImageSpace::CreateBootImage()

    • MarkZygoteStart()
    • FindImageFilenameImpl()
    • 判断
      • found_image && has_system && has_cache
        • 若ChecksumsMatch()匹配,则会Load
          • ImageSpaceLoader::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()
  • 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()
      • 映射文件大小为image_size_, 只包括ImageHeader+data, 不包括padding + bitmap部分.
    • 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)
          • space->ValidateOatFile()

    • 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容