8009981: nashorn tests fail with -XX:+VerifyStack
Summary: nmethod::preserve_callee_argument_oops() must take appendix into account.
Reviewed-by: kvn, twisti
--- a/hotspot/src/share/vm/code/nmethod.cpp Thu May 30 08:37:08 2013 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Fri May 31 14:40:26 2013 +0200
@@ -1976,11 +1976,10 @@
if (!method()->is_native()) {
SimpleScopeDesc ssd(this, fr.pc());
Bytecode_invoke call(ssd.method(), ssd.bci());
- // compiled invokedynamic call sites have an implicit receiver at
- // resolution time, so make sure it gets GC'ed.
- bool has_receiver = !call.is_invokestatic();
+ bool has_receiver = call.has_receiver();
+ bool has_appendix = call.has_appendix();
Symbol* signature = call.signature();
- fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
+ fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f);
}
#endif // !SHARK
}
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Thu May 30 08:37:08 2013 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Fri May 31 14:40:26 2013 +0200
@@ -635,18 +635,22 @@
// at an uncommon trap for an invoke (where the compiler
// generates debug info before the invoke has executed)
Bytecodes::Code cur_code = str.next();
- if (cur_code == Bytecodes::_invokevirtual ||
- cur_code == Bytecodes::_invokespecial ||
- cur_code == Bytecodes::_invokestatic ||
- cur_code == Bytecodes::_invokeinterface) {
+ if (cur_code == Bytecodes::_invokevirtual ||
+ cur_code == Bytecodes::_invokespecial ||
+ cur_code == Bytecodes::_invokestatic ||
+ cur_code == Bytecodes::_invokeinterface ||
+ cur_code == Bytecodes::_invokedynamic) {
Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci());
Symbol* signature = invoke.signature();
ArgumentSizeComputer asc(signature);
cur_invoke_parameter_size = asc.size();
- if (cur_code != Bytecodes::_invokestatic) {
+ if (invoke.has_receiver()) {
// Add in receiver
++cur_invoke_parameter_size;
}
+ if (i != 0 && !invoke.is_invokedynamic() && MethodHandles::has_member_arg(invoke.klass(), invoke.name())) {
+ callee_size_of_parameters++;
+ }
}
if (str.bci() < max_bci) {
Bytecodes::Code bc = str.next();
@@ -661,6 +665,7 @@
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic:
case Bytecodes::_invokeinterface:
+ case Bytecodes::_invokedynamic:
case Bytecodes::_athrow:
break;
default: {
--- a/hotspot/src/share/vm/runtime/frame.cpp Thu May 30 08:37:08 2013 -0700
+++ b/hotspot/src/share/vm/runtime/frame.cpp Fri May 31 14:40:26 2013 +0200
@@ -1008,6 +1008,7 @@
OopClosure* _f;
int _offset; // the current offset, incremented with each argument
bool _has_receiver; // true if the callee has a receiver
+ bool _has_appendix; // true if the call has an appendix
frame _fr;
RegisterMap* _reg_map;
int _arg_size;
@@ -1027,19 +1028,20 @@
}
public:
- CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, OopClosure* f, frame fr, const RegisterMap* reg_map)
+ CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
: SignatureInfo(signature) {
// initialize CompiledArgumentOopFinder
_f = f;
_offset = 0;
_has_receiver = has_receiver;
+ _has_appendix = has_appendix;
_fr = fr;
_reg_map = (RegisterMap*)reg_map;
- _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
+ _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0) + (has_appendix ? 1 : 0);
int arg_size;
- _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, &arg_size);
+ _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &arg_size);
assert(arg_size == _arg_size, "wrong arg size");
}
@@ -1049,12 +1051,16 @@
_offset++;
}
iterate_parameters();
+ if (_has_appendix) {
+ handle_oop_offset();
+ _offset++;
+ }
}
};
-void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) {
+void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f) {
ResourceMark rm;
- CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map);
+ CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
finder.oops_do();
}
--- a/hotspot/src/share/vm/runtime/frame.hpp Thu May 30 08:37:08 2013 -0700
+++ b/hotspot/src/share/vm/runtime/frame.hpp Fri May 31 14:40:26 2013 +0200
@@ -411,7 +411,7 @@
oop* oopmapreg_to_location(VMReg reg, const RegisterMap* regmap) const;
// Oops-do's
- void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f);
+ void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f);
void oops_interpreted_do(OopClosure* f, CLDToOopClosure* cld_f, const RegisterMap* map, bool query_oop_map_cache = true);
private:
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu May 30 08:37:08 2013 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri May 31 14:40:26 2013 +0200
@@ -2726,7 +2726,7 @@
return regs.first();
}
-VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, int* arg_size) {
+VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, bool has_appendix, int* arg_size) {
// This method is returning a data structure allocating as a
// ResourceObject, so do not put any ResourceMarks in here.
char *s = sig->as_C_string();
@@ -2770,6 +2770,11 @@
default : ShouldNotReachHere();
}
}
+
+ if (has_appendix) {
+ sig_bt[cnt++] = T_OBJECT;
+ }
+
assert( cnt < 256, "grow table size" );
int comp_args_on_stack;
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu May 30 08:37:08 2013 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Fri May 31 14:40:26 2013 +0200
@@ -410,7 +410,7 @@
// Convert a sig into a calling convention register layout
// and find interesting things about it.
- static VMRegPair* find_callee_arguments(Symbol* sig, bool has_receiver, int *arg_size);
+ static VMRegPair* find_callee_arguments(Symbol* sig, bool has_receiver, bool has_appendix, int *arg_size);
static VMReg name_for_receiver();
// "Top of Stack" slots that may be unused by the calling convention but must