8145137: Incorrect call signature can be used in nmethod::preserve_callee_argument_oops

Reviewed-by: roland, jrose
This commit is contained in:
Vladimir Ivanov 2015-12-11 15:03:11 +03:00
parent e56a7de478
commit 1a4c3a752d
4 changed files with 30 additions and 13 deletions

View file

@ -2332,11 +2332,22 @@ bool nmethod::detect_scavenge_root_oops() {
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 @@ Method* nmethod::attached_method(address call_instr) {
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
}