On Jan 20, 2016, at 4:13 AM, Remi Forax <fo...@univ-mlv.fr> wrote: > > I understand that having the VM that may always recompile may be seen as a > bug, > but having the VM that bailout and stop recompiling, or more generally change > the compilation strategy is a bug too.
As you can guess from my previous message, I agree with this, except for "change the compilation strategy". The JVM earns its way in the world by routinely changing compilation strategy. The reason most people don't notice is the strategy changes are profile-driven and self-correcting. Nothing in the 292 world promises a particular strategy, just a best effort to create and execute great code, assuming stable application behavior. When an optimization breaks, the JVM's strategy may also fail to adjust correctly. One symptom of that is infinite recompilation, usually because one line of code is being handled badly, but which creates huge bloat in the code cache for thousands of lines of code that happen to be inlined nearby. We try hard to avoid this. We also try hard to detect this problem. That is the true meaning of those strange cutoffs. Nobody things falling into the interpreter is a good idea, except that it, on balance, is a better idea than (a) throwing an assertion error, or (b) filling the CPU with JIT jobs and the code cache with discards. The third choice (c) run offending method in the interpreter at least preserves a degree of forward progress, while allowing the outraged user to report a bug. The correct fix to the bug, IMO, is never to jump from (c) to (a) or (b). It is to find and fix the problem with the compilation strategy, and the profile-driven gating logic for it. If your car's transmission gets a bug (now that they are computers, they can), what would you prefer? (a) stop the car immediately, (b) run the car in first gear at full speed, or (c) slow the car to a defined speed limit (25mph). Detroit prefers, and the JVM implements, option (c). > The problem here is that there is no way from the point of view of a dyn lang > runtime to know what will be the behavior of the VM for a callsite if the VM > decide to stop to recompile, decide to not inline, decide to inline some part > of the tree, etc. Yes. And it usually doesn't matter; the issue doesn't come up until something breaks, or we find a performance pothole. The current problem is (in my mind) a break, not a performance pothole that needs tuning. If we fix the break, people shouldn't need to worry about this stuff, usually. > Said differently, using an invokedynamic allows to create code shapes that > will change dynamically, if the VM behavior also changes dynamically, it's > like building a wall on moving parts, the result is strange dynamic behaviors > that are hard to diagnose and reproduce. JVMs have always been like that, because of dynamic class loading, but with indy it is more so, since it's much easier to "override" some previously fixed behavior. > The recompilation behavior of the VM should be keep simple and predicatable, > basically, the VM should always recompile the CS with no failsafe switch. We agree that the failsafe should not trip. Just like we agree that the circuit breakers in our building should not trip. We disagree, perhaps, about what to do when they trip. I don't want to duct-tape them back into the "on" position; do you? > If dyn lang runtime devs have trouble with that, they can already use an > exactInvoker to simulate an indirect mh call and we can even provide new > method handle combiners to gracefully handle multi-stable CS. That's all true. The new combiners might have some sort of handshake with the JVM to self-adjust their code shape. But I claim the baseline behavior that I have called for is the most generally useful, since it is able to amortize recompilation resources over multiple CS misses, put global limits on total recompilation effort, and preserve reasonable forward progress executing good-enough code. (Having a CS change force a reoptimization is tantamount to adding a JIT control API, as Compiler.recompile(cs) like System.gc(). But just for CS-bearing methods. We are a long way from understanding how to work such an API.) Idea: Perhaps CS's should have a callback which says, "Hey, CS, the JIT has mispredicted you a bunch of times; would you like to nominate an alternative representation?" The call would be made asynchronously, outside the JIT. The default behavior would be to say "nope" with the results given above, but the CS could also return a MH (perhaps the CS.dynamicInvoker, or perhaps some more elaborate logic), which the JVM would slide into place over the top of the CS. Despite the fact that CS bindings are final, the new binding would take its place. And it would be the user's choice whether that binding pointed to the old CS or a new CS or some combination of both. — John _______________________________________________ mlvm-dev mailing list firstname.lastname@example.org http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev