InterfaceCalls

Version 1 by john.rose
on Jul 19, 2008 01:24.

compared with
Current by john.rose
on Jul 19, 2008 02:26.

Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (1)

View page history

It is a curious fact that the searching process described above, while currently a linear search over an array embedded in the receiver's klassOop, could also be implemented, with roughly equivalent performance, as a pointer-chasing search over a linked-list representation of implemented interfaces. Indeed, some languages use pointer chasing for dynamic lookup. The advantage of such a representation is a looser coupling between a class and its methods (or in JVM terms, its itables; an itable may contain either single methods or groups of methods). The looser coupling would allow a class to extend its implemented interfaces in a type-safe and compatible manner, just as a SmallTalk class can add new methods with a modest amount of pointer swapping.

h3. Sample Code
Since most call sites are monomorphic, they complete very quickly; see the monomorphic sample code under [VirtualCalls].

Here is a generic instruction trace of a polymorphic interface call.

{noformat:title=polymorphic call to an interface method}
callSite:
set #calledInterface, CHECK
call #itableStub[itableSlot]
---
itableStub[itableSlot]:
load (RCVR + #klass), KLASS_TEM
load (KLASS_TEM + #vtableSize), TEM
add (KLASS_TEM + TEM), SCAN_TEM
tryAgain:
# this part is repeated zero or more times, usually zero
load (SCAN_TEM + #itableEntry.interface), TEM
cmp TEM, CHECK
jump,eq foundInterface
test TEM
jump,z noSuchInterface
inc #sizeof(itableEntry), SCAN_TEM
jump tryAgain
tryAgain:
load (SCAN_TEM + #itableEntry.interface), TEM
cmp TEM, CHECK
jump,eq foundInterface
foundInterface:
load (SCAN_TEM + #itableEntry.offset), TEM
load (KLASS_TEM + TEM + #itableSlot), METHOD
load (METHOD + #compiledEntry), TEM
jump TEM
---
compiledEntry:
...
{noformat}

In all, that is six memory references and two nonlocal jumps.

Note that the intermediate "itable stub" is customized to the itable offset (which is always small and often zero). It is not customized to the interface; the call site uses the CHECK register (also used by monomorphic calls) to transmit the desired interface.

For some other approaches to reducing the cost of this operation, see [Faster Interface Invocation|http://openjdk.java.net/projects/mlvm/subprojects.html#interface-perf] in the Da Vinci Machine Project pages.

(The alert reader will note that updating the call site from its monomorphic state to its polymorphic state requires a two-word MP-safe transaction. This is simulated by "bungee patching", in which the target of the call is temporarily patched to a safely initialized copy of the desired call site. This extra indirection is later retracted at a safe moment, by the routine {{ICStub::finalize}}.)

The individuals who post here are part of the extended Sun Microsystems community and they might not be employed or in any way formally affiliated with Sun Microsystems. The opinions expressed here are their own, are not necessarily reviewed in advance by anyone but the individual authors, and neither Sun nor any other party necessarily agrees with them.

Copyright 1994-2009 Sun Microsystems, Inc.
Powered by Atlassian Confluence
Sun Guidelines on Public Discourse Privacy Policy Terms of Use Trademarks Site Map Employment Investor Relations Contact