JDK-8056071 : compiler/whitebox/IsMethodCompilableTest.java fails with 'method() is not compilable after 3 iterations'
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u31,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-08-26
  • Updated: 2015-12-16
  • Resolved: 2014-11-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u40Fixed 9 b42Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Seen this failure in testing.


----------System.err:(27/1900)----------
java.lang.RuntimeException: private int SimpleTestCase$Helper.method() is not compilable after 3 iterations
	at IsMethodCompilableTest.test(IsMethodCompilableTest.java:107)
	at CompilerWhiteBoxTest.runTest(CompilerWhiteBoxTest.java:174)
	at CompilerWhiteBoxTest.main(CompilerWhiteBoxTest.java:131)
	at IsMethodCompilableTest.main(IsMethodCompilableTest.java:56)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:484)
	at com.sun.javatest.regtest.MainWrapper$MainThread.run(MainWrapper.java:94)
	at java.lang.Thread.run(Thread.java:745)
java.lang.RuntimeException: private int SimpleTestCase$Helper.method() is not compilable after 3 iterations
	at IsMethodCompilableTest.test(IsMethodCompilableTest.java:107)
	at CompilerWhiteBoxTest.runTest(CompilerWhiteBoxTest.java:174)
	at CompilerWhiteBoxTest.main(CompilerWhiteBoxTest.java:131)
	at IsMethodCompilableTest.main(IsMethodCompilableTest.java:56)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:484)
	at com.sun.javatest.regtest.MainWrapper$MainThread.run(MainWrapper.java:94)
	at java.lang.Thread.run(Thread.java:745)

Comments
Problems with the current implementation: 1) We should always use the MDO if it is valid, even if there is no corresponding nmethod. Otherwise we compile trivial methods at level 4 or start profiling again. 2) If there is a nmethod the MDO may still be invalid: We can compile a method immediately at C2, deoptimize, and the MDO is uninitialized. In this case we wrongly assume that the method is trivial and re-compile it at C1. 3) To avoid a level 2 or 3 compilation and profiling we should mark simple constant getter methods, like those used by the test, as trivial (see trivial.log and trivial_fixed.log). 4) We should add verification code to avoid/catch such bad tiered level transitions.
05-11-2014

ILW = Bad tiered transition, medium likelihood, no workaround = MMH = P3
05-11-2014

This is not a testbug. Analysis: The test compiles and deoptimizes a method m multiple times. After each deoptimization the test checks if m was compiled with C2 and if so increments a counter. The test assumes that m is compilable until the counter reaches the 'PerMethodRecompilationCutoff'. This assumption does not hold in the following case: - The first compilation request for m is added to the compile queue. Although we profiled m and the MDO suggests that m is trivial, we do not use this information because due to deoptimization there is no corresponding nmethod [1]. We therefore compile at level 4 and execution continues in the interpreter [2]. - A second compilation request for m is issued and while it is being processed the first compilation request finishes [3]. Because a nmethod now exists, we use the MDO and decide to compile at level 1 since m is trivial. - The level 4 compiled nmethod is replaced by the new level 1 nmethod. After the following deoptimization the counter is not incremented because the nmethod was last compiled at level 1. As a result m is set to not compilable before the counter reaches the 'PerMethodRecompilationCutoff'. The test fails. [1] See implementation of 'SimpleThresholdPolicy::is_trivial(..)' [2] First compilation request: InterpreterRuntime::frequency_counter_overflow InterpreterRuntime::frequency_counter_overflow_inner SimpleThresholdPolicy::event AdvancedThresholdPolicy::method_invocation_event AdvancedThresholdPolicy::call_event AdvancedThresholdPolicy::common [is_trivial() returns false because no nmethod available] [next_level = CompLevel_Full_Optimization] SimpleThresholdPolicy::compile SimpleThresholdPolicy::submit_compile CompileBroker::compile_method CompileBroker::compile_method_base CompileBroker::create_compile_task [continue execution in interpreter] [3] Second compilation request: InterpreterRuntime::frequency_counter_overflow InterpreterRuntime::frequency_counter_overflow_inner SimpleThresholdPolicy::event AdvancedThresholdPolicy::method_invocation_event [First compilation finishes here -> !CompileBroker::compilation_is_in_queue()] AdvancedThresholdPolicy::call_event AdvancedThresholdPolicy::common [is_trivial() returns true because nmethod/mdo now available] [next_level = CompLevel_Simple] [CompLevel_Simple nmethod replaced CompLevel_Full_Optimization method]
05-11-2014

ILW=Test Fail - fragile impl, no real bug suspected; 3 times - Intermittently; none=LLH=P5
29-08-2014

[~iignatyev], any idea what the problem could be?
27-08-2014