Wed, 05 Jun 2019 03:07:31 +0100
8222670: pathological case of JIT recompilation and code cache bloat
Summary: Prevent downgraded compilation tasks from recompiling.
Reviewed-by: sgehwolf, thartmann, andrew
1.1 --- a/src/share/vm/compiler/compileBroker.cpp Mon Jun 03 16:14:54 2019 +0100 1.2 +++ b/src/share/vm/compiler/compileBroker.cpp Wed Jun 05 03:07:31 2019 +0100 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -751,8 +751,10 @@ 1.11 No_Safepoint_Verifier nsv; 1.12 task = CompilationPolicy::policy()->select_task(this); 1.13 } 1.14 - remove(task); 1.15 - purge_stale_tasks(); // may temporarily release MCQ lock 1.16 + if (task != NULL) { 1.17 + remove(task); 1.18 + purge_stale_tasks(); // may temporarily release MCQ lock 1.19 + } 1.20 return task; 1.21 } 1.22
2.1 --- a/src/share/vm/compiler/compileBroker.hpp Mon Jun 03 16:14:54 2019 +0100 2.2 +++ b/src/share/vm/compiler/compileBroker.hpp Wed Jun 05 03:07:31 2019 +0100 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -339,7 +339,6 @@ 2.11 2.12 static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, TRAPS); 2.13 static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count); 2.14 - static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level); 2.15 static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level); 2.16 static bool is_compile_blocking (); 2.17 static void preload_classes (methodHandle method, TRAPS); 2.18 @@ -389,6 +388,7 @@ 2.19 return NULL; 2.20 } 2.21 2.22 + static bool compilation_is_complete(methodHandle method, int osr_bci, int comp_level); 2.23 static bool compilation_is_in_queue(methodHandle method); 2.24 static int queue_size(int comp_level) { 2.25 CompileQueue *q = compile_queue(comp_level);
3.1 --- a/src/share/vm/oops/instanceKlass.cpp Mon Jun 03 16:14:54 2019 +0100 3.2 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Jun 05 03:07:31 2019 +0100 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -2925,6 +2925,13 @@ 3.11 3.12 // On-stack replacement stuff 3.13 void InstanceKlass::add_osr_nmethod(nmethod* n) { 3.14 +#ifndef PRODUCT 3.15 + if (TieredCompilation) { 3.16 + nmethod * prev = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), n->comp_level(), true); 3.17 + assert(prev == NULL || !prev->is_in_use(), 3.18 + "redundunt OSR recompilation detected. memory leak in CodeCache!"); 3.19 + } 3.20 +#endif 3.21 // only one compilation can be active 3.22 NEEDS_CLEANUP 3.23 // This is a short non-blocking critical region, so the no safepoint check is ok. 3.24 @@ -3046,7 +3053,9 @@ 3.25 osr = osr->osr_link(); 3.26 } 3.27 OsrList_lock->unlock(); 3.28 - if (best != NULL && best->comp_level() >= comp_level && match_level == false) { 3.29 + 3.30 + assert(match_level == false || best == NULL, "shouldn't pick up anything if match_level is set"); 3.31 + if (best != NULL && best->comp_level() >= comp_level) { 3.32 return best; 3.33 } 3.34 return NULL;
4.1 --- a/src/share/vm/prims/whitebox.cpp Mon Jun 03 16:14:54 2019 +0100 4.2 +++ b/src/share/vm/prims/whitebox.cpp Wed Jun 05 03:07:31 2019 +0100 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -633,6 +633,25 @@ 4.11 } 4.12 WB_END 4.13 4.14 +WB_ENTRY(void, WB_MarkMethodProfiled(JNIEnv* env, jobject o, jobject method)) 4.15 + jmethodID jmid = reflected_method_to_jmid(thread, env, method); 4.16 + CHECK_JNI_EXCEPTION(env); 4.17 + methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 4.18 + 4.19 + MethodData* mdo = mh->method_data(); 4.20 + if (mdo == NULL) { 4.21 + Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR); 4.22 + mdo = mh->method_data(); 4.23 + } 4.24 + mdo->init(); 4.25 + InvocationCounter* icnt = mdo->invocation_counter(); 4.26 + InvocationCounter* bcnt = mdo->backedge_counter(); 4.27 + // set i-counter according to AdvancedThresholdPolicy::is_method_profiled 4.28 + // because SimpleThresholdPolicy::call_predicate_helper uses > in jdk8u, that's why we need to plus one. 4.29 + icnt->set(InvocationCounter::wait_for_compile, Tier4MinInvocationThreshold + 1); 4.30 + bcnt->set(InvocationCounter::wait_for_compile, Tier4CompileThreshold + 1); 4.31 +WB_END 4.32 + 4.33 template <typename T> 4.34 static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*)) { 4.35 if (name == NULL) { 4.36 @@ -1123,6 +1142,8 @@ 4.37 CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation}, 4.38 {CC"clearMethodState", 4.39 CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, 4.40 + {CC"markMethodProfiled", 4.41 + CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_MarkMethodProfiled}, 4.42 {CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag}, 4.43 {CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag}, 4.44 {CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag},
5.1 --- a/src/share/vm/runtime/advancedThresholdPolicy.cpp Mon Jun 03 16:14:54 2019 +0100 5.2 +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Jun 05 03:07:31 2019 +0100 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -196,6 +196,16 @@ 5.11 5.12 if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile 5.13 && is_method_profiled(max_method)) { 5.14 + 5.15 + if (CompileBroker::compilation_is_complete(max_method, max_task->osr_bci(), CompLevel_limited_profile)) { 5.16 + if (PrintTieredEvents) { 5.17 + print_event(REMOVE_FROM_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); 5.18 + } 5.19 + compile_queue->remove_and_mark_stale(max_task); 5.20 + max_method->clear_queued_for_compilation(); 5.21 + return NULL; 5.22 + } 5.23 + 5.24 max_task->set_comp_level(CompLevel_limited_profile); 5.25 if (PrintTieredEvents) { 5.26 print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/compiler/tiered/Level2RecompilationTest.java Wed Jun 05 03:07:31 2019 +0100 6.3 @@ -0,0 +1,92 @@ 6.4 +/* 6.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + */ 6.26 + 6.27 +/** 6.28 + * @test Level2RecompilationTest 6.29 + * @summary Test downgrading mechanism from level 3 to level 2 for those profiled methods. 6.30 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox 6.31 + * @build Level2RecompilationTest 6.32 + * @run main ClassFileInstaller sun.hotspot.WhiteBox 6.33 + * @run main/othervm -Xbootclasspath/a:. -XX:+TieredCompilation 6.34 + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-UseCounterDecay 6.35 + * -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* 6.36 + * -XX:CompileCommand=print,SimpleTestCase$Helper::* 6.37 + * Level2RecompilationTest 6.38 + */ 6.39 +public class Level2RecompilationTest extends CompLevelsTest { 6.40 + public static void main(String[] args) throws Throwable { 6.41 + if (CompilerWhiteBoxTest.skipOnTieredCompilation(false)) { 6.42 + throw new RuntimeException("Test isn't applicable for non-tiered mode"); 6.43 + } 6.44 + String[] testcases = {"METHOD_TEST", "OSR_STATIC_TEST"}; 6.45 + CompilerWhiteBoxTest.main(Level2RecompilationTest::new, testcases); 6.46 + } 6.47 + 6.48 + protected Level2RecompilationTest(TestCase testCase) { 6.49 + super(testCase); 6.50 + // to prevent inlining of #method 6.51 + WHITE_BOX.testSetDontInlineMethod(method, true); 6.52 + } 6.53 + 6.54 + @Override 6.55 + protected void test() throws Exception { 6.56 + if (skipXcompOSR()) { 6.57 + return; 6.58 + } 6.59 + 6.60 + checkNotCompiled(); 6.61 + int bci = WHITE_BOX.getMethodEntryBci(method); 6.62 + WHITE_BOX.markMethodProfiled(method); 6.63 + if (testCase.isOsr()) { 6.64 + // for OSR compilation, it must be the begin of a BB. 6.65 + // c1_GraphBulider.cpp:153 assert(method()->bci_block_start().at(cur_bci), ... 6.66 + bci = 0; 6.67 + } 6.68 + 6.69 + WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_FULL_PROFILE, bci); 6.70 + checkCompiled(); 6.71 + checkLevel(COMP_LEVEL_LIMITED_PROFILE, getCompLevel()); 6.72 + 6.73 + for (int i=0; i<100; ++i) { 6.74 + WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_FULL_PROFILE, bci); 6.75 + waitBackgroundCompilation(); 6.76 + checkLevel(COMP_LEVEL_LIMITED_PROFILE, getCompLevel()); 6.77 + } 6.78 + } 6.79 + 6.80 + @Override 6.81 + protected void checkLevel(int expected, int actual) { 6.82 + if (expected == COMP_LEVEL_FULL_PROFILE 6.83 + && actual == COMP_LEVEL_LIMITED_PROFILE) { 6.84 + // for simple method full_profile may be replaced by limited_profile 6.85 + if (IS_VERBOSE) { 6.86 + System.out.printf("Level check: full profiling was replaced " 6.87 + + "by limited profiling. Expected: %d, actual:%d\n", 6.88 + expected, actual); 6.89 + } 6.90 + return; 6.91 + } 6.92 + super.checkLevel(expected, actual); 6.93 + } 6.94 +} 6.95 +
7.1 --- a/test/compiler/whitebox/CompilerWhiteBoxTest.java Mon Jun 03 16:14:54 2019 +0100 7.2 +++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java Wed Jun 05 03:07:31 2019 +0100 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -328,11 +328,11 @@ 7.11 return; 7.12 } 7.13 final Object obj = new Object(); 7.14 - for (int i = 0; i < 10 7.15 + for (int i = 0; i < 100 7.16 && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) { 7.17 synchronized (obj) { 7.18 try { 7.19 - obj.wait(1000); 7.20 + obj.wait(100); 7.21 } catch (InterruptedException e) { 7.22 Thread.currentThread().interrupt(); 7.23 }
8.1 --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Mon Jun 03 16:14:54 2019 +0100 8.2 +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Wed Jun 05 03:07:31 2019 +0100 8.3 @@ -162,6 +162,7 @@ 8.4 } 8.5 public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci); 8.6 public native void clearMethodState(Executable method); 8.7 + public native void markMethodProfiled(Executable method); 8.8 public native int getMethodEntryBci(Executable method); 8.9 public native Object[] getNMethod(Executable method, boolean isOsr); 8.10