前言
本文旨在提高即时编译器中消息发送的效率。尽管参考了Smalltalk,但这个问题适用于大多数动态JIT编译的语言。
问题
给定一个消息发送站点,它可以被分类为单态、多态或巨态。如果消息发送的接收者始终是相同类型,则为单态发送,例如
10 timesRepeat: [Object new].
new
的接收者始终为 Object
。对于这种情况,JIT 会生成单态内联缓存。
有时一个给定的发送站点会引用几种不同的对象类型,例如:
#(1 'a string' 1.5) do: [:element | element print]
在这种情况下,
print
被发送到不同类型的对象。对于这些情况,JIT通常会发出多态内联缓存。当消息发送到不仅是一些而是许多不同的对象类型时,就会发生巨型多态消息发送。其中最突出的例子之一是这个:
Behavior>>#new
^self basicNew initialize
这里,
basicNew
创建对象,然后initialize
进行初始化。你可以这样做:Object new
OrderedCollection new
Dictionary new
他们将都执行相同的Behavior>>#new方法。由于initialize在许多类中的实现不同,PIC将很快填满。我对这种发送站点很感兴趣,知道它们只偶尔发生(仅有1%的发送是megamorphic)。
问题
有哪些可能和具体的优化方法可以避免在megamorphic发送站点进行查找?