Source for this example https://github.com/AdoptOpenJDK/jitwatch/blob/master/core/src/main/resources/examples/MegamorphicBypass.java
public class MegamorphicBypass
{
public interface Coin { void deposit(); }
public class Nickel implements Coin { public void deposit() { moneyBox += 5; } }
public class Dime implements Coin { public void deposit() { moneyBox += 10; } }
public class Quarter implements Coin { public void deposit() { moneyBox += 25; } }
public static int moneyBox = 0;
public MegamorphicBypass()
{
Coin nickel = new Nickel();
Coin dime = new Dime();
Coin quarter = new Quarter();
Coin coin = null;
final int maxImplementations = 3;
for (int i = 0; i < 1_000_000; i++)
{
switch(i % maxImplementations)
{
case 0: coin = nickel; break;
case 1: coin = dime; break;
case 2: coin = quarter; break;
}
// peel off one type with an instanceof check
if (coin instanceof Nickel)
{
coin.deposit();
}
else
{
// this callsite will now only observe 2 types and can use bimorphic inlining
coin.deposit();
}
}
System.out.println("moneyBox:" + moneyBox);
}
public static void main(String[] args) {
new MegamorphicBypass();
}
}
{
public interface Coin { void deposit(); }
public class Nickel implements Coin { public void deposit() { moneyBox += 5; } }
public class Dime implements Coin { public void deposit() { moneyBox += 10; } }
public class Quarter implements Coin { public void deposit() { moneyBox += 25; } }
public static int moneyBox = 0;
public MegamorphicBypass()
{
Coin nickel = new Nickel();
Coin dime = new Dime();
Coin quarter = new Quarter();
Coin coin = null;
final int maxImplementations = 3;
for (int i = 0; i < 1_000_000; i++)
{
switch(i % maxImplementations)
{
case 0: coin = nickel; break;
case 1: coin = dime; break;
case 2: coin = quarter; break;
}
// peel off one type with an instanceof check
if (coin instanceof Nickel)
{
coin.deposit();
}
else
{
// this callsite will now only observe 2 types and can use bimorphic inlining
coin.deposit();
}
}
System.out.println("moneyBox:" + moneyBox);
}
public static void main(String[] args) {
new MegamorphicBypass();
}
}