Mercurial > hg > openjdk > jdk9 > hotspot
changeset 9774:8962380eb039
8145137: Incorrect call signature can be used in nmethod::preserve_callee_argument_oops
Reviewed-by: roland, jrose
author | vlivanov |
---|---|
date | Fri, 11 Dec 2015 15:03:11 +0300 |
parents | 891e9c2ac3b2 |
children | eeaef3c57176 3455d28791c8 |
files | src/share/vm/code/nmethod.cpp src/share/vm/code/nmethod.hpp src/share/vm/runtime/sharedRuntime.cpp test/compiler/jsr292/NonInlinedCall/InvokeTest.java |
diffstat | 4 files changed, 30 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/code/nmethod.cpp Thu Dec 10 14:51:54 2015 +0300 +++ b/src/share/vm/code/nmethod.cpp Fri Dec 11 15:03:11 2015 +0300 @@ -2332,11 +2332,22 @@ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { #ifndef SHARK if (method() != NULL && !method()->is_native()) { - SimpleScopeDesc ssd(this, fr.pc()); + address pc = fr.pc(); + SimpleScopeDesc ssd(this, pc); Bytecode_invoke call(ssd.method(), ssd.bci()); bool has_receiver = call.has_receiver(); bool has_appendix = call.has_appendix(); Symbol* signature = call.signature(); + + // The method attached by JIT-compilers should be used, if present. + // Bytecode can be inaccurate in such case. + Method* callee = attached_method_before_pc(pc); + if (callee != NULL) { + has_receiver = !(callee->access_flags().is_static()); + has_appendix = false; + signature = callee->signature(); + } + fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f); } #endif // !SHARK @@ -3526,3 +3537,11 @@ return NULL; // not found } +Method* nmethod::attached_method_before_pc(address pc) { + if (NativeCall::is_call_before(pc)) { + NativeCall* ncall = nativeCall_before(pc); + return attached_method(ncall->instruction_address()); + } + return NULL; // not a call +} +
--- a/src/share/vm/code/nmethod.hpp Thu Dec 10 14:51:54 2015 +0300 +++ b/src/share/vm/code/nmethod.hpp Fri Dec 11 15:03:11 2015 +0300 @@ -512,6 +512,7 @@ void copy_values(GrowableArray<Metadata*>* metadata); Method* attached_method(address call_pc); + Method* attached_method_before_pc(address pc); // Relocation support private:
--- a/src/share/vm/runtime/sharedRuntime.cpp Thu Dec 10 14:51:54 2015 +0300 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri Dec 11 15:03:11 2015 +0300 @@ -1078,10 +1078,7 @@ address pc = vfst.frame_pc(); { // Get call instruction under lock because another thread may be busy patching it. MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag); - if (NativeCall::is_call_before(pc)) { - NativeCall* ncall = nativeCall_before(pc); - return caller_nm->attached_method(ncall->instruction_address()); - } + return caller_nm->attached_method_before_pc(pc); } return NULL; }
--- a/test/compiler/jsr292/NonInlinedCall/InvokeTest.java Thu Dec 10 14:51:54 2015 +0300 +++ b/test/compiler/jsr292/NonInlinedCall/InvokeTest.java Fri Dec 11 15:03:11 2015 +0300 @@ -74,23 +74,23 @@ } static class T implements I { - @DontInline public Class<?> f1() { if (doDeopt) WB.deoptimize(); return T.class; } - @DontInline public static Class<?> f2() { if (doDeopt) WB.deoptimize(); return T.class; } - @DontInline private Class<?> f4() { if (doDeopt) WB.deoptimize(); return T.class; } + @DontInline public Class<?> f1() { if (doDeopt) WB.deoptimizeAll(); return T.class; } + @DontInline public static Class<?> f2() { if (doDeopt) WB.deoptimizeAll(); return T.class; } + @DontInline private Class<?> f4() { if (doDeopt) WB.deoptimizeAll(); return T.class; } } static class P1 extends T { - @DontInline public Class<?> f1() { if (doDeopt) WB.deoptimize(); return P1.class; } - @DontInline public Class<?> f3() { if (doDeopt) WB.deoptimize(); return P1.class; } + @DontInline public Class<?> f1() { if (doDeopt) WB.deoptimizeAll(); return P1.class; } + @DontInline public Class<?> f3() { if (doDeopt) WB.deoptimizeAll(); return P1.class; } } static class P2 extends T { - @DontInline public Class<?> f1() { if (doDeopt) WB.deoptimize(); return P2.class; } - @DontInline public Class<?> f3() { if (doDeopt) WB.deoptimize(); return P2.class; } + @DontInline public Class<?> f1() { if (doDeopt) WB.deoptimizeAll(); return P2.class; } + @DontInline public Class<?> f3() { if (doDeopt) WB.deoptimizeAll(); return P2.class; } } static interface I { - @DontInline default Class<?> f3() { if (doDeopt) WB.deoptimize(); return I.class; } + @DontInline default Class<?> f3() { if (doDeopt) WB.deoptimizeAll(); return I.class; } } @DontInline