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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容