21

Why certain code patterns when present within JVM internal classes are turned into an intrinsic function, whereas the same patterns when called from my own class are not.

Example:

bitCount function, when called from within Integer.bitCount(i) will be turned into an intrinsic. But when copied into my class and then called will take much longer to execute.

Compare

Integer.bitCount(i) 
MyClass.bitCount(i) 


public static int bitCount(int i) {
    // HD, Figure 5-2
    i = i - ((i >>> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    i = (i + (i >>> 4)) & 0x0f0f0f0f;
    i = i + (i >>> 8);
    i = i + (i >>> 16);
    return i & 0x3f;
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
Mark
  • 821
  • 7
  • 14
  • 4
    the list of intrinsic methods is hard coded in the JVM so by construction, your own methods won't be in there... If you run your method long enough, it should get compiled anyway and there should not be a material difference with an intrinsic... – assylias Nov 10 '13 at 16:55

2 Answers2

32

The answer is simple: an intrinsic function is defined in this way because a faster, native way to obtain the result of the function exists and it is applied in case thanks to a specified mapping.

That's not something related to compilation at all. Integer.bitCount is special in the sense that implementation is marked to be replaceable with a native asm instruction POPCNT. Basically this native instruction is used when using the Integer.bitCount function (if the CPU supports that instruction), when you declare your own copy of the function the normal implementation is used.

Why JVM is able to recognize that the function can be optimized? Because it's hardcoded somewhere in the JDK, that has nothing to do with similarity to the code.

Jack
  • 131,802
  • 30
  • 241
  • 343
  • 2
    @Mark: C compilers do recognize some patterns, like [`(x << n ) | (x >> (32-n))` as a rotate](http://stackoverflow.com/questions/776508/best-practices-for-circular-shift-rotate-operations-in-c/776523#776523). It would be possible for a JVM to recognize that sequence of mask/shift/add as a bitCount and use whatever the ideal implementation was, but apparently your JVM doesn't have a pattern-recognizer for that pattern. C compilers need that kind of pattern-recognition more than Java, because C doesn't have a single standard library that portable code can use for rotates/popcnt/etc. – Peter Cordes Mar 19 '16 at 22:22
7

The JVM has a list of methods, usually native ones, which is replaces with inlined machine code. This list appears in intrinsic header file in the OpenJDK though I can't find a link to it on the web.

See from line 581 in the link @Jack provided vmSymbols.hpp

cgrand
  • 7,939
  • 28
  • 32
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130