I had very good discussion yesterday with Serguei Spitsyn from serviceability.
He said that we may not need one solution. Both cases, monitoring and debugging, are important and
we can use different solutions for them.
As Andrew said, for monitoring you want to observe the same behavior as in production. I think we
should not restrict JIT and others optimizations in this case. I also agree with Richard that JVMTI
may report scalar replaced objects and elided monitors in this mode if requested - it is also
interesting information.
For debugging we may want to see locals and monitors present in compiled code and it is reasonable
to avoid optimizations which remove them. But even for debugging we may want to use optimized code
as we do when debugging optimized C code (we don't expect to see all locals in such case).
May be we should check not which JVMTI capabilities are switched on but for what JVMTI is used for.
Or add API for user to ask what he wants.
As Richard mentioned in some email compiled frame can't be deoptimized (to get objects and monitors
back) if it is not top frame on stack. So we can't rely on deoptimization here. JIT and Runtime need
to know what to do with optimizations when agent is attached to JVM.
I don't like suggestion for 8230956 to switch off EA when can_tag_objects is on. Based on
declaration, can_tag_objects is always on. Which means we will have EA off in all cases including
monitoring tools (JFR, managment, profiling) which is not acceptable for me.
I share David's concern about missing cases for some JVMTI capabilities which are not checked when
JIT decides to use optimizations. And I think it will be troublesome to go through all capabilities
old and new to see if we need to add checks.
For me as JIT compiler engineer it would be much simpler to ask JVMTI should optimizations be
switched off or not and let JVMTI find in which case it is used and make decision instead of current
case when JIT checks some JVMTI capabilities.
I agree to provide information in compiled code for JVMTI - we do provide information about scalar
replaced object already.
And I think it would be much easier to document such relation between JIT and
JVMTI.
Thanks,
Vladimir
On 9/25/19 7:32 AM, Andrew Dinn wrote:
On 25/09/2019 13:31, Reingruber, Richard wrote:
> The terminology clarification is simply that - a clarification so that
> when the spec says "heap" it means "Java heap", when it says "Thread" it
> means "Java thread" etc without having to spell it out each time. I do
> not read this as meaning anything about an "abstract virtual machine"
> state, it is about the Java Virtual Machine state - which to mean can be
> the concrete state as implemented by Hotspot, not some abstract
> conceptual model state.
It is more than that. It is the glue to the JVM and Java Language
specifications. This is important
to accept. Otherwise I would suggest to do your java debugging with gdb and
Intel (or AMD??) x86
manuals at your hand.
> We'll just have to agree to disagree here.
Agreed. All I do is offer my points to our audience hoping for a few '+1' ;)
Sorry, but I'm going to throw in a -1 here, not on any grounds of
textual exegesis of the JVM spec rather those of simple pragmatism --
grounds that David already alluded to in his mention of finalization.
The path you want to go down is to force disabling of optimizations as
needed in order to ensure that JVMTI agents see a 'pure' version of the
/abstract/ machine state as defined in the Java Virtual Machine spec.
This is in many ways laudable:
1) such a 'pure' view is one that can be mapped fairly directly back to
the original Java application code state (assuming you factor in enough
knowledge of how javac translates code to bytecode and relying on the
fact that javac does not do anything very tricksy by way of optimization
during that translation) i.e. it is clear.
2) this pure view is going to be unchanged by whatever tricks the JIT
and/or JVM might have up their sleeves i.e. it is consistent/repeatable.
That latter point of consistency is, perhaps, more significant than the
former one of clarity since for most programmers bytecode is only ever
observed 'through a glass darkly'.
The downside comes when you consider why you might want to use an agent.
Primarily, JVMTI was provided for monitoring actual program execution.
Agents can also be used to modify program execution, making program
transformations that result in locally and/or globally variant
behaviour. Well, actually, I guess some monitoring operations falls into
that latter camp.
In order to pursue your proposed path it is going to be necessary to
disable, either piecemeal or wholesale, a variety of JIT optimizations.
This would mean that use of an agent might involve a cost that is
prohibitive.
Primarily, that's a cost in performance (whether measured in space or
time). When it comes to monitoring it is also the extra cost in the
accuracy of any report of what is being monitored -- if installation of
an agent or use of a montoring capability means you run different code
in a different way then you can end up measuring apples not pears.
That possible inaccuracy has to be weighed against other inaccuracies
that arise when the JIT invalidates or changes notifications of all the
events the idealized version of the abstract machine would imply. Where
the balance lies depends on the specifics of which optimizations are
disabled and the needs/behaviour of the app.
I believe that was what David was talking about when he mentioned as an
example the case of finalizers being run 'early' for non-reachable
objects. The optimization here allows early reclamation of objects and
reuse of stack slots. The cost is that object appear to go out of scope
'before' their fields are read -- at least as far as the source/abstract
machine view of 'before' is defined. How much that cost imposes on users
is unclear but the cost was discounted because finalization is already a
highly unreliable mechanism -- i.e. who cares?
So, I agree with David's general argument that we have to be pragmatic
about these things as he said taking into account
" - how important it would be to accurately interact with things as
expressed at the source level
- the cost of disabling or reversing the optimisation when needed; and
- the overall cost and complexity it adds to the development and
maintenance of the JVM"
regards,
Andrew Dinn
-----------
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in England and Wales under Company Registration No. 03798903
Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander