4

My understanding is that an optimization is valid if it has no observable effect that contradicts the JLS. So for example, the JIT compiler can optimize away "do nothing" code in an inner loop.

But I don't recalling a definitive statement to this effect.

Does anyone know of a definitive statement (i.e. in the JLS or a document of similar standing) of when a Java optimization (e.g. performed by the native code compiler) is valid?

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Typically the single threaded scenario is simple. Multithreaded is annoying since there some optimizations can be observed, in particular reordering of memory reads/writes. Which reorderings are allowed depends on the memory model, but I don't know which memory model the java standard specifies. – CodesInChaos Mar 20 '11 at 09:59
  • Sure, for example: `code_statement; // “valid” optimization`. – Margus Mar 20 '11 at 10:25
  • @CodeInChaos - actually, reordering of reads / writes is an area where the rules are clearly specified. – Stephen C Mar 20 '11 at 13:46
  • @CodeInChaos: The optimizer is allowed to do every optimization that won't change the single threaded execution of the program, so we can do quite a lot. – Voo Mar 20 '11 at 18:21
  • @Voo Interesting. So the memory of Java is much weaker than that in .net. – CodesInChaos Mar 20 '11 at 18:43
  • @CodeInChaos: Wait in .NET you can only optimize things that won't influence the multi threaded execution of a program? That would eliminate quite a number of extremely useful optimizations, which I somehow doubt - any source for that? Maybe just a misunderstanding, also with Java5 and the extended volatile definition I don't see how Java should have a weaker memory model. – Voo Mar 20 '11 at 19:19
  • @Voo in .net you can only reorder some stuff, but not everything. By weaker I meant that it makes less guarantees about the order in which stuff happens, giving the optimizer for freedom. Personally I think a weak model is better since it forces you to use special functions if you want stronger ordering properties thus forcing you to make it explicit that you rely on ordering. See http://blogs.msdn.com/b/jaredpar/archive/2008/01/17/clr-memory-model.aspx for how the .net memory model works. – CodesInChaos Mar 20 '11 at 19:24
  • @CodeInChaos: Yes I understood what you meant with "weaker", I'm just surprised that .NET differs itself in that aspect, because I find a weak memory model together with Java5's volatile variables the most sensible approach. Will read up a bit about the CLR's memory model - thanks for the links. – Voo Mar 20 '11 at 20:41
  • @Voo this is not quite true. Current java ensures the happens before ordering of some things: synchronization, thread.start(), thread.join(), and volatile impose happens before relationship that are externally visible. Also constructors are guaranteed to complete before finalizers are called. http://java.sun.com/docs/books/jls/third_edition/html/memory.html – Philip JF Aug 06 '11 at 02:50

3 Answers3

3

The JLS and the JVM spec both specify what the behavior of any Java statement is (or for the JVM spec how bytecodes work, etc.), but they say nothing about how that behavior is to occur. It's implicit in the two documents that any implementation that correctly implements the abstract behavior specified is considered a compliant Java implementation. The main idea behind having an abstract standard is to specify what observable behaviors must be shared across all implementations without going into the details of what makes those behaviors occur. For this reason, implementations and their optimizers are allowed to do whatever they feel is necessary and proper to make the code run, so long as they don't deviate from the specified semantics.

Hope this helps!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • Yes ... but can you point to somewhere in the specs that talks about observable behavior, and says what is and what is not observable? (My gut feeling is that this is the approach taken ... but I wanted some explicit confirmation.) – Stephen C Mar 20 '11 at 13:45
1

A compiler optimization is valid as long as it doesn't make code behave differently from the standard. This applies for all languages.

I don't think there's a need to specifically state this fact, as the only requirement for a standards compliant compiler is that it behaves as the standard describes. An optimization that doesn't change its apparent behavior obviously doesn't change whether it's standards compliant or not.

Matti Virkkunen
  • 63,558
  • 9
  • 127
  • 159
  • Maybe there is. For instance, the aggressive optimization of loops (to the extend of deleting them entirely) is "observable" to folks who write naive benchmarks. It would be nice if you could point to somewhere in the specs that says explicitly that such optimizations are "valid". (And I think that they *should be* ... ) – Stephen C Mar 20 '11 at 13:50
  • @Stephen C: Optimizations can quite well be observable (they would be pretty pointless if they did *nothing*), but I'm pretty sure the spec doesn't say much about the execution time for things. As long as the optimizations don't change anything the spec specifies (execution speed is something I hope it doesn't), they make no difference with regard to standards-compliance. – Matti Virkkunen Mar 20 '11 at 15:58
  • @Stephen C: The spec is absolutely not interested in speed, as long as the observed behavior (i.e. results of the program) is correct everything's fine. Also the optimizer can do anything that won't change the execution of a single threaded program, e.g. observing that a loop variable is only read not written and therefore replacing a loop with while(true) - which will lead to problems with programs that set the variable in another thread (obviously only if the variable is not volatile) – Voo Mar 20 '11 at 18:25
1

For example the String pool as mentioned here is a form of optimization. Similar concepts exists afaik for small values of Integer and Long.

Maybe you find more interesting answers here and an explanation of the Integer pool here.

Community
  • 1
  • 1
user unknown
  • 35,537
  • 11
  • 75
  • 121