[讨论] hotspot没实现Megamorphic inline caching?

nkhanxh 2012-02-17
看撒加的资料里面没提到。

有些疑问。

In this scheme once a send falls-off the end of a polymorphic inline cache a megamorphic cache specific to the call site's selector is created (or shared if one already exists), and the send site is relinked to call it. The code can be significantly more efficient than a normal first-level method lookup probe since the selector is now a constant, which decreases register pressure, the code for the lookup and dispatch is executed without calling into the run-time, and the dispatch can benefit from branch prediction.

这里面“the selector is now a constant”是根据所调用的函数名字生成的对吗?

对于“first-level method lookup”,是否他是全局的,就是对应所有虚函数调用的?否则为何selector不是constant?这句话似乎也暗示了这点?

“A megamorphic inline cache can be implemented by creating code to perform a first-level method lookup for a particular call-site. ”似乎就是对于某个特定site的“first-level method lookup”?

另外,没太明白“dispatch can benefit from branch prediction.”是为什么,难道不是查找的表来确定调用哪个函数吗?怎么会受益于硬件的分支检测?难道是指所谓的“非确定跳转”的分支预测?印象中书上说这个东西不是很准,不太容易正确预测。

RednaxelaFX 2012-02-17
你在引用文献的时候不写出处是来自Wikipedia,别人很难知道你在说什么…

HotSpot VM没有实现megamorphic inline cache。
hotspot/src/share/vm/code/compiledIC.hpp
//-----------------------------------------------------------------------------
// The CompiledIC represents a compiled inline cache.
//
// In order to make patching of the inline cache MT-safe, we only allow the following
// transitions (when not at a safepoint):
//
//
//         [1] --<--  Clean -->---  [1]
//            /       (null)      \
//           /                     \      /-<-\
//          /          [2]          \    /     \
//      Interpreted  ---------> Monomorphic     | [3]
//  (compiledICHolderOop)        (klassOop)     |
//          \                        /   \     /
//       [4] \                      / [4] \->-/
//            \->-  Megamorphic -<-/
//                  (methodOop)
//
// The text in paranteses () refere to the value of the inline cache receiver (mov instruction)
//
// The numbers in square brackets refere to the kind of transition:
// [1]: Initial fixup. Receiver it found from debug information
// [2]: Compilation of a method
// [3]: Recompilation of a method (note: only entry is changed. The klassOop must stay the same)
// [4]: Inline cache miss. We go directly to megamorphic call.
//
// The class automatically inserts transition stubs (using the InlineCacheBuffer) when an MT-unsafe
// transition is made to a stub.

这就是最相关的文档了。在到达megamorphic的时候这个compiled inline cache就会退化为一个普通的vtable查找形式的virtual call。

要是想看相关的一些实验,我有做过比较乱的笔记:https://gist.github.com/1344520

以前也写过另一片笔记,关于DLR的早期版本里的inline cache的实现,http://rednaxelafx.iteye.com/blog/241430
nkhanxh 2012-02-17
呵呵抱歉,我有时候发问比较突兀,标题和内容不太搭调。
首先,从文档看起来似乎缺少的是“polymorphic”,很奇怪。
//         [1] --<--  Clean -->---  [1]
//            /       (null)      \
//           /                     \      /-<-\
//          /          [2]          \    /     \
//      Interpreted  ---------> Monomorphic     | [3]
//  (compiledICHolderOop)        (klassOop)     |
//          \                        /   \     /
//       [4] \                      / [4] \->-/
//            \->-  Megamorphic -<-/
//                  (methodOop)
//

不过这些倒不是我特别关心的,我其实只是想从mental model上理解一下这些东西。
我觉得很奇怪,为什么说megamorphic时候的inline cache能比“first-level method lookup“快。看了上下文,感觉似乎他是说对一个特定的call site建立特定的first level method lookup。这样selector是常量。也就是说,不用比较selector了,只要比较class type即可。并且可以获得硬件内置的分支预测支持。

是不是由于这个call site specific 查找表理论上比vtable更有效,因为他是把所有本方法的特定实现组织成一个表,只要一次间接,而不是像vtable要两次间接。 并且这样更加cache 友好?可能这就是inline的含义?

但是所谓的分支预测是怎么来的呢?难道指的就是间接跳转分支预测,但是别的方法不是一样能利用这点么?只不过来的晚一点,必须到vtable那层找到才行?
Global site tag (gtag.js) - Google Analytics