@diggaa1984: Also, das ist so:
Der Bytecode-Compiler (das Ding, das aus java-Dateien class-Dateien macht) kompiliert für die Java VM. Diese virtuelle Maschine hat einen virtuellen Prozessor, so wie auch jede reale Maschine einen realen Prozessor hat. Und so ein Prozessor (egal ob real oder virtuell) hat einen bestimmten Befehlssatz. Gerade dieser Befehlssatz ist ein sehr wesentliches Unterscheidungsmerkmal bei Prozessoren.
Java erreicht die Plattformunabhängigkeit unter anderem dadurch, dass eben nicht für einen real existierenden Prozessor kompiliert wird, sondern nur für einen virtuellen (nämlich den der VM). Ein Compiler muss sich immer auf eine bestimmte Zielsprache einstellen bzw. ist allein dafür geschaffen worden, Quelltexte einer ganz bestimmten Sprache in die Sprache eines bestimmten Prozessors zu übersetzen.
Da der Bytecode-Compiler als Zielsprache die des virtuellen Prozessors hat, kann er auch nur in Befehle übersetzen, die für diesen virtuellen Prozessor verfügbar sind. Ob da Befehle zum Überprüfen einzelner Bits zur Verfügung stehen, kann ich gerade nicht sagen, halte ich aber für eher unwahrscheinlich. Das muss aber noch gar nicht so viel sagen.
Denn zur Laufzeit muss noch ein JIT-Compiler oder Interpreter ran. Der Interpreter ist im Wesentlichen eine Schleife, die entsprechend dem aktuellen Befehlscode ein Stückchen nativen Code aufruft, der dann ausgeführt wird. Der JIT-Compiler erkennt genauso die Befehle wie der Interpreter, führt sie aber nicht sofort aus, sondern schreibt sie sich vielmehr erst einmal auf. Wenn dann der Compiler genügend Code aufgeschrieben hat, ist er möglicherweise in der Lage, größere Zusammenhänge zwischen kleinen Codestückchen zu finden, und kann dann Optimierungen vornehmen.
Aber auch hier ist wieder einmal der Compiler an die Zielsprache gebunden. Wenn also der Befehlssatz des realen Prozessors einen Befehl kennt, um einzelne Bits zu prüfen, dann kann(!) der Compiler eventuell auf die Idee kommen, tatsächlich auch diesen Befehl dann, wenn es angebracht ist, einzusetzen.
Solche Optimierungen zur Laufzeit kosten zunächst einmal Zeit, denn es muss erst einmal kompiliert werden (vom Befehlssatz des virtuellen Prozessors zum Befehlssatz des realen Prozessors). Das erhöht die Latenz, aber auch die Geschwindigkeit.
Der Bytecode-Compiler erzeugt Code für einen virtuellen Prozessor, dessen Arbeitsweise eher an Stackmaschinen erinnert. Der JIT-Compiler dagegen muss diesen Bytecode in die Maschinensprache des realen Prozessors übersetzen. Dieser reale Prozessor erinnert eher an Registermaschinen. Ein wesentlicher Teil der Zeit wird damit verbracht, die Daten, die sonst auf dem Stack liegen, Registern zuzuweisen. Gerade hier kann der JIT-Compiler viel verbessern (um nicht zu sagen optimieren), und da ist es schon eine sehr hohe Kunst, ganz spezielle Befehle des realen Prozessors zu finden, die an dieser Stelle genutzt werden können. (Immerhin soll das Programm ja schnell kompiliert sein, und da muss der JIT-Compiler irgendwann fertig werden bzw. mit Optimieren aufhöhren.) Insofern kann es hier sehr auf die JIT-Compiler ankommen, ob so ein spezieller Befehl benutzt werden wird oder nicht.
Kurzum: Ob spezielle Befehle genutzt werden (können), hängt von sehr, sehr vielen Dingen ab.
Ark