什么是Incremental Link Table[转]

想想如果我们自己要做编译器(compiler)和连接器(linker),当然希望编译连接运行得越快越好,同时也希望产生的二进制代码也是又快又小,上帝是公平的,鱼与熊掌不可兼得,所以我们自然想到用两种build方式,一种Release,编译慢一些,但是产生的二进制代码紧凑精悍,一种Debug,编译运行快,产生的代码臃肿一点没关系,Debug版本嘛,就是指望程序员在开发的时候反复的build,为了不浪费程序员的时候,要想尽办法让编译连接速度变快。

假如一个程序有连续两个 foo bar ( 所谓连续,就是他们编译连接之后函数体连续存放 ) foo 入口位置在 0x0400 ,长度为 0x200 个字节,那么 bar 入口就应该在 0x0600 = 0x0400+0x0200 。程序员在开发的时候总是频繁的修改 code 然后 build ,假如程序员在 foo 里面增加了一些内容,现在 foo 函数体占 0x300 个字节了, bar 的入口也就只好往后移 0x100 变成了 0x0700 ,这样就有一个问题,如果 foo 在程序中被调用了 n 次,那么 linker 不得不修改这 n 个函数调用点,虽然 linker 不嫌累,但是 link 时间长了,程序员会觉得不爽。所以 MSVC Debug 版的 build ,不会让各个函数体之间这么紧凑,每个函数体后都有 padding (全是汇编代码 int 3 ,作用是引发中断,这样因为古怪原因运行到不该运行的 padding 部分,会发生异常),有了这些 padding ,就可以一定程度上缓解上面提到的问题,不过当函数增加内容太多超过 padding ,还是有问题,怎么办呢? MSVC Debug build 中用上了 Incremental Link Table ILT 其实就是一串 jmp 语句,每个 jmp 语句对应一个函数, jmp 的目的地就是函数的入口点,和没有 ILT 的区别是,现在对函数的调用不是直接 call 到函数入口点了,而是 call ILT 中对应的位置,而这个位置上什么也不做,直接 jmp 到函数中去。这样的好处是,当一个函数入口地址改变时,只要修改 ILT 中对应值就搞定了,用不着修改每一个调用位置,用一个冗余的 ITL 把时间复杂度从 O(n) 将为 O(1) ,值得,当然 Debug 版的二进制文件会稍大稍慢, Release 版不会用上 ILT
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值