提交 35de3fa1 编写于 作者: T thartmann

8061817: Whitebox.deoptimizeMethod() does not deoptimize all OSR versions of method

Summary: Fixed Whitebox.deoptimizeMethod() to deoptimize all OSR versions of the method.
Reviewed-by: kvn, iignatyev
上级 42c7b605
...@@ -2890,6 +2890,22 @@ void InstanceKlass::remove_osr_nmethod(nmethod* n) { ...@@ -2890,6 +2890,22 @@ void InstanceKlass::remove_osr_nmethod(nmethod* n) {
OsrList_lock->unlock(); OsrList_lock->unlock();
} }
int InstanceKlass::mark_osr_nmethods(const Method* m) {
// This is a short non-blocking critical region, so the no safepoint check is ok.
MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag);
nmethod* osr = osr_nmethods_head();
int found = 0;
while (osr != NULL) {
assert(osr->is_osr_method(), "wrong kind of nmethod found in chain");
if (osr->method() == m) {
osr->mark_for_deoptimization();
found++;
}
osr = osr->osr_link();
}
return found;
}
nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_level, bool match_level) const { nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_level, bool match_level) const {
// This is a short non-blocking critical region, so the no safepoint check is ok. // This is a short non-blocking critical region, so the no safepoint check is ok.
OsrList_lock->lock_without_safepoint_check(); OsrList_lock->lock_without_safepoint_check();
......
...@@ -783,6 +783,7 @@ class InstanceKlass: public Klass { ...@@ -783,6 +783,7 @@ class InstanceKlass: public Klass {
void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; }; void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; };
void add_osr_nmethod(nmethod* n); void add_osr_nmethod(nmethod* n);
void remove_osr_nmethod(nmethod* n); void remove_osr_nmethod(nmethod* n);
int mark_osr_nmethods(const Method* m);
nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const; nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const;
// Breakpoint support (see methods on Method* for details) // Breakpoint support (see methods on Method* for details)
......
...@@ -793,6 +793,10 @@ class Method : public Metadata { ...@@ -793,6 +793,10 @@ class Method : public Metadata {
return method_holder()->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL; return method_holder()->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL;
} }
int mark_osr_nmethods() {
return method_holder()->mark_osr_nmethods(this);
}
nmethod* lookup_osr_nmethod_for(int bci, int level, bool match_level) { nmethod* lookup_osr_nmethod_for(int bci, int level, bool match_level) {
return method_holder()->lookup_osr_nmethod(this, bci, level, match_level); return method_holder()->lookup_osr_nmethod(this, bci, level, match_level);
} }
......
...@@ -404,19 +404,10 @@ WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jbool ...@@ -404,19 +404,10 @@ WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jbool
CHECK_JNI_EXCEPTION_(env, result); CHECK_JNI_EXCEPTION_(env, result);
MutexLockerEx mu(Compile_lock); MutexLockerEx mu(Compile_lock);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
nmethod* code;
if (is_osr) { if (is_osr) {
int bci = InvocationEntryBci; result += mh->mark_osr_nmethods();
while ((code = mh->lookup_osr_nmethod_for(bci, CompLevel_none, false)) != NULL) { } else if (mh->code() != NULL) {
code->mark_for_deoptimization(); mh->code()->mark_for_deoptimization();
++result;
bci = code->osr_entry_bci() + 1;
}
} else {
code = mh->code();
}
if (code != NULL) {
code->mark_for_deoptimization();
++result; ++result;
} }
result += CodeCache::mark_for_deoptimization(mh()); result += CodeCache::mark_for_deoptimization(mh());
......
/*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import sun.hotspot.WhiteBox;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
/*
* @test DeoptimizeMultipleOSRTest
* @bug 8061817
* @library /testlibrary /testlibrary/whitebox
* @build DeoptimizeMultipleOSRTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,DeoptimizeMultipleOSRTest::triggerOSR DeoptimizeMultipleOSRTest
* @summary testing of WB::deoptimizeMethod()
*/
public class DeoptimizeMultipleOSRTest {
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
private static final long BACKEDGE_THRESHOLD = 150000;
private Method method;
private int counter = 0;
public static void main(String[] args) throws Exception {
DeoptimizeMultipleOSRTest test = new DeoptimizeMultipleOSRTest();
test.test();
}
/**
* Triggers two different OSR compilations for the same method and
* checks if WhiteBox.deoptimizeMethod() deoptimizes both.
*
* @throws Exception
*/
public void test() throws Exception {
method = DeoptimizeMultipleOSRTest.class.getDeclaredMethod("triggerOSR", boolean.class, long.class);
// Trigger two OSR compiled versions
triggerOSR(true, BACKEDGE_THRESHOLD);
triggerOSR(false, BACKEDGE_THRESHOLD);
// Wait for compilation
CompilerWhiteBoxTest.waitBackgroundCompilation(method);
// Deoptimize
WHITE_BOX.deoptimizeMethod(method, true);
if (WHITE_BOX.isMethodCompiled(method, true)) {
throw new AssertionError("Not all OSR compiled versions were deoptimized");
}
}
/**
* Triggers OSR compilations by executing loops.
*
* @param first Determines which loop to execute
* @param limit The number of loop iterations
*/
public void triggerOSR(boolean first, long limit) {
if (limit != 1) {
// Warmup method to avoid uncommon traps
for (int i = 0; i < limit; ++i) {
triggerOSR(first, 1);
}
CompilerWhiteBoxTest.waitBackgroundCompilation(method);
}
if (first) {
// Trigger OSR compilation 1
for (int i = 0; i < limit; ++i) {
counter++;
}
} else {
// Trigger OSR compilation 2
for (int i = 0; i < limit; ++i) {
counter++;
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册