Question

Given the same major version, say Java 7, do different Java Compilers (e.g., Oracle's hotspot, JRockit, or IBM's J9 etc...) compile a given java source code file into the same bytcode?

Scanning the Java 7 language spec it would seem that what is being discussed is the semantics of the language and not the transformation of the code into bytecode.

This question is not the same as do different major.minor versions for a given vendor produce the same bytecode. That question is already answered here - with a could be.

From the following answer to Is the creation of Java class files deterministic? and a comment to that answer that refers to this along side two answers to the major.minor question above 1 and 2, I gather that the answer to my question is YES.

Excerpts for the above are:

The JLS leaves many implementation details to vary from one implementation to another.

and

However the JLS does not specify a 1:1 mapping from source code to the generated byte code, so you should not rely on the exact same byte code to be generated.

Yet a comment here implies differently:

It’s the compiler, i.e. javac, creating the code using a BLAH BLAH BLAH. This has nothing to do with HotSpot.

It implies that given a code X all javac implementations (same version/different vendors) must produce the same Y bytecode.

I cannot see how that is so, but I am unable to verify that it is not (or that what I think, see above) is correct.

Can a definitive answer be given?

Was it helpful?

Solution

There are differences between the compilers and interestingly some of the permitted differences led to problems in the past.

Some differences are small, e.g. some compilers optimize x=x+1 to produce the same bytecode as x++, others don’t.

Others can have more impact, e.g. the standard did not specify how to generate the names of synthetic members used to implement inner class access to private members (and similar things) in the past (I don’t know whether it does today). But the algorithm for calculating a default serialVersionUID used a hash code over all class members, even synthetic ones.

As a consequence, compiling with javac or the first Eclipse versions created classes with incompatible serialVersionUIDs. Today, Eclipse uses the same name schema for synthetic members as javac and issues a warning about missing explicit serialVersionUIDs in Serializable classes by default.

There’s still a lot of freedom and even packing with pack200 and unpacking may create classes with different byte code than the original classes.

OTHER TIPS

There are 2 questions:

  1. Are different java compilers free to generate different bytecode for the same sourrce code?
  2. Do they actually produce different bytecode for the same source.

The answer to 1 is yes, obviously. For, otherwise, the JLS had to fully specify the bytecode to generate for each and every language construct. But it doesn't.

The answer to 2 I don't know for sure, though I have heard that eclipse compiler generates slightly different code than javac in some cases. Should be easy to verify.

The comment in question does not actually disagree. Note that you are mixing up two different things here: Java bytecode compilers (javac) and Java just-in-time compilers (such as HotSpot or J9). You normally use some javac implementation to translate java source code to java bytecode.

Then you take the bytecode and execute it in a JVM, which uses another compiler.

Again, there are two sets of compilers:

  1. Bytecode compilers (.java to .class)
  2. Just-in-time compilers as part of Java virtual machines (execute .class files)

(EDIT: Neither of these are guaranteed to produce identical results (i.e., the same java file can yield different class files, and the same class file can yield different machine code when the JIT is done with it.))

The reason for having two sequential compilation processes is that if you wrap everything into one compiler, you lose two properties:

  1. your compiled program will be platform-specific
  2. your program will not (easily) be able to perform some of the optimisations and advanced language features (reflection, dynamic class loading) that Java provides.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top