RFR (S/M): 8012547: Reclamation of flushed methods can be slow
Nils Eliasson
nils.eliasson at oracle.com
Wed Apr 24 07:06:54 PDT 2013
Hi again,
Further testing revealed that not all issues was fully identified.
Flushing could still cause compiles to halt even though compilations was
on, and turning off compilations when the code cache was really full
made the sweeper run much less often, prolonging the problem.
Change log:
* Fix the comment Christian mentioned, and some other comments too.
* find_and_remove_saved_code renamed to reanimate_saved_code to
distinguish it from remove_saved_code that actually removes it.
* dont bail out on need_flushing() in compile_method - that causes us to
stop compiling as soon as we hit CodeCacheFlushingMinimumFreeSpace - and
that wasn't the idea.
* New product flag CodeCacheFlushingFraction (defaults to 2)
* _was_full removed. Was a redundant way to say that we stopped
compilations.
* _last_was_full renamed to _last_full_flush_time, to emphasize that it
is the time when we hit the hard limit CodeCacheMinimumSpace and
compilations are stopped
* _was_full_traversal renamed to _last_flush_traversal_id. 'full' means
the hard CodeCacheMinimumFreeSpace limit in all other variable names.
* introduced _dead_compile_ids that hold a count for the number of
compile ID that have been reclaimed. Gives a more accurate way to flush
the cache.
* Simplified scan_stacks
- restore flush token when min interval has passed
- start compilations again if flushing is no longer needed
* Speed up sweeper when compilations is turned off. Sweeping is slowed
down when compiler threads are sleeping on the CodeCache lock, and we
want to speed up the reclaim process so that we can turn on compiler again.
* Let sweeper make disconnected methods non_entrant even if we don't
need flushing any more. Makes us less likely to hit a new flush.
* Refactored NMethodSweeper::handle_full_code_cache
- flushed and full flushes now uses the same token to synchronize -
otherwise we might get two back-to-back flushes. And that doesn't help
anyone.
- remove time check - flush_token is restored in scan_stacks where
the time is already checked.
* set _resweep flag when flushing.
The code is much easier to read now and the behavior should be less
surprising.
http://cr.openjdk.java.net/~neliasso/8012547/webrev.03/
<http://cr.openjdk.java.net/%7Eneliasso/8012547/webrev.03/>
Thanks,
Nils Eliasson
On 2013-04-18 15:09, Nils Eliasson wrote:
> Hi!
>
> I have another fix to the code cache sweeper and flushing that needs a
> review.
>
> The major change is to remove a check in scan_stacks that stops the
> sweeper when the cache is getting full. The normal mode is to sweep
> and record if any change has happened that require another sweep. This
> check stops the sweeper early causing some methods that are
> speculatively disconnected to stay so for an unnecessary long time
> sometimes causing unnecessary new flushes.
>
> Also some refactoring
> - remove state variable _do_sweep that was unnecessary. It marked if a
> sweep was active or not, but just a duplicate way of checking if any
> methods are being sweept (nmethodsweeper::current != NULL).
> - rename _rescan to _resweep. When _resweep is set there will be
> another sweep started when the current ends. That sweep will start
> with a scan, but it is not only a scan.
> - rename _advise_to_sweep to _flush_token. Is CASed by the first
> thread that wants to flush and reset by scan_stacks when the flush is
> finished and a proper time has passed.
>
> http://cr.openjdk.java.net/~neliasso/8012547/
> <http://cr.openjdk.java.net/%7Eneliasso/8012547/>
> https://jbs.oracle.com/bugs/browse/JDK-8012547
>
> Thanks,
> Nils E.
More information about the hotspot-compiler-dev
mailing list