使变形调用站点更有效的不同技术有哪些

mel*_*des 8 optimization performance jit smalltalk vm-implementation

前言

这是关于提高JIT编译器中的消息发送效率.尽管提到了Smalltalk,但这个问题适用于大多数动态JIT编译语言.

问题

给定一个消息发送站点,它可以被分类为单态,多态变形.如果发送的消息的接收者总是相同类型,则它是单态发送,如

10 timesRepeat: [Object new].
Run Code Online (Sandbox Code Playgroud)

new总是接收者的地方Object.对于这种发送,JIT发出单态内联缓存.

有时,给定的发送站点会引用一些不同的对象类型,例如:

#(1 'a string' 1.5) do: [:element | element print]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,print被发送到不同类型的对象.对于这些情况,JIT通常会发出多态内联缓存.

当消息不仅仅发送到同一个地方的许多不同对象类型时,就会发生变形消息发送.其中一个最突出的例子是:

Behavior>>#new
    ^self basicNew initialize
Run Code Online (Sandbox Code Playgroud)

在这里,basicNew创建对象,然后进行initialize初始化.你可以这样做:

Object new
OrderedCollection new
Dictionary new
Run Code Online (Sandbox Code Playgroud)

并且它们都将执行相同的行为>> #new方法.由于初始化的实现在很多类中是不同的,因此PIC将很快填充.我对这种发送网站感兴趣,知道它们只是不经常发生(只有1%的发送是变形的).

对于变形发送站点有哪些可能的和特定的优化来避免进行查找?

mel*_*des 3

我想象了一些,并想了解更多。PIC 满后,我们必须调用查找(无论是满的还是全局缓存的),但为了优化我们可以:

  • 回收 PIC,丢弃所有条目(许多条目可能是旧的且不经常使用)。
  • 调用某种特定的超态查找(即,将所有先前分派的类型缓存在由类型哈希访问的数组中)。
  • 内联包含方法(内联时,发送站点可能会停止变态)