Skip to content

Commit

Permalink
Partial escape analysis failure example
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswhocodes committed Dec 18, 2016
1 parent 35c4fb4 commit 6388135
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions core/src/main/resources/examples/PartialEscapeFail.java
@@ -0,0 +1,57 @@
public class PartialEscapeFail
{
public static class EscapeConsumer {
public int smallEnoughToInline(Integer integer) { // 325 bytes of bytecode (inlining limit is 325)
int i = integer.intValue();
return ((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + 1;
}

public int tooBigToInline(Integer integer) { // 329 bytes of bytecode (inlining limit is 325)
int i = integer.intValue();
return ((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + ((i + 3) >> 2) + ((i + 4) >> 2) + ((i + 5) >> 2) + ((i + 6) >> 2) + ((i + 7) >> 2) + ((i + 8) >> 2) +
((i + 1) >> 2) + ((i + 2) >> 2) + 1 + 999; // javac is not an optimising compiler ;)
}
}

public String run()
{
long result = 0;

EscapeConsumer consumer = new EscapeConsumer();

java.util.Random random = new java.util.Random();

for (int i = 0; i < 100_000_000; i++)
{
Integer integer = new Integer(i);

if (random.nextBoolean())
{
result += consumer.smallEnoughToInline(integer);
}
else
{
// if you get an ArgEscape on any path you're busted
result += consumer.tooBigToInline(integer);
}
}

return "Result: " + result;
}

public static void main(final String[] args)
{
System.out.println(new PartialEscapeFail().run());
}
}

1 comment on commit 6388135

@thomaswue
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running on the Graal compiler on HotSpot inlines both methods and completely removes the Integer allocation. To test partial escape analysis, it is more reliable to store the value into a persistent data structure (e.g., hash map) in one path.

Please sign in to comment.