Skip to content

Commit a34861a

Browse files
author
duke
committed
Backport 20ea218ce52f79704445acfe2d4a3dc9d04e86d2
1 parent 48f11a4 commit a34861a

File tree

11 files changed

+158
-14
lines changed

11 files changed

+158
-14
lines changed

src/hotspot/cpu/aarch64/abstractInterpreter_aarch64.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ void AbstractInterpreter::layout_activation(Method* method,
150150

151151
#ifdef ASSERT
152152
if (caller->is_interpreted_frame()) {
153-
assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
153+
assert(locals <= caller->interpreter_frame_expression_stack(), "bad placement");
154+
assert(locals >= interpreter_frame->sender_sp() + max_locals - 1, "bad placement");
154155
}
155156
#endif
156157

src/hotspot/cpu/arm/abstractInterpreter_arm.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@ void AbstractInterpreter::layout_activation(Method* method,
132132

133133
intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
134134

135+
#ifdef ASSERT
136+
if (caller->is_interpreted_frame()) {
137+
// Test exact placement on top of caller args
138+
intptr_t* l2 = caller->interpreter_frame_last_sp() + caller_actual_parameters - 1;
139+
assert(l2 <= caller->interpreter_frame_expression_stack(), "bad placement");
140+
assert(l2 >= locals, "bad placement");
141+
}
142+
#endif
143+
135144
interpreter_frame->interpreter_frame_set_locals(locals);
136145
BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
137146
BasicObjectLock* monbot = montop - moncount;

src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,15 @@ void AbstractInterpreter::layout_activation(Method* method,
129129
caller->interpreter_frame_esp() + caller_actual_parameters :
130130
caller->sp() + method->max_locals() - 1 + (frame::java_abi_size / Interpreter::stackElementSize);
131131

132+
#ifdef ASSERT
133+
if (caller->is_interpreted_frame()) {
134+
assert(locals_base <= caller->interpreter_frame_expression_stack(), "bad placement");
135+
const int caller_abi_bytesize = (is_bottom_frame ? frame::top_ijava_frame_abi_size : frame::parent_ijava_frame_abi_size);
136+
intptr_t* l2 = caller->sp() + method->max_locals() - 1 + (caller_abi_bytesize / Interpreter::stackElementSize);
137+
assert(locals_base >= l2, "bad placement");
138+
}
139+
#endif
140+
132141
intptr_t* monitor_base = caller->sp() - frame::ijava_state_size / Interpreter::stackElementSize;
133142
intptr_t* monitor = monitor_base - (moncount * frame::interpreter_frame_monitor_size());
134143
intptr_t* esp_base = monitor - 1;

src/hotspot/cpu/riscv/abstractInterpreter_riscv.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ void AbstractInterpreter::layout_activation(Method* method,
142142

143143
#ifdef ASSERT
144144
if (caller->is_interpreted_frame()) {
145-
assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
145+
assert(locals <= caller->interpreter_frame_expression_stack(), "bad placement");
146+
assert(locals >= interpreter_frame->sender_sp() + max_locals - 1, "bad placement");
146147
}
147148
#endif
148149

src/hotspot/cpu/s390/abstractInterpreter_s390.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,13 @@ void AbstractInterpreter::layout_activation(Method* method,
183183
intptr_t* sender_sp;
184184
if (caller->is_interpreted_frame()) {
185185
sender_sp = caller->interpreter_frame_top_frame_sp();
186+
#ifdef ASSERT
187+
assert(locals_base <= caller->interpreter_frame_expression_stack(), "bad placement");
188+
// Test caller-aligned placement vs callee-aligned
189+
intptr_t* l2 = (caller->sp() + method->max_locals() - 1 +
190+
frame::z_parent_ijava_frame_abi_size / Interpreter::stackElementSize);
191+
assert(locals_base >= l2, "bad placement");
192+
#endif
186193
} else if (caller->is_compiled_frame()) {
187194
sender_sp = caller->fp() - caller->cb()->frame_size();
188195
// The bottom frame's sender_sp is its caller's unextended_sp.

src/hotspot/cpu/x86/abstractInterpreter_x86.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ void AbstractInterpreter::layout_activation(Method* method,
8888

8989
#ifdef ASSERT
9090
if (caller->is_interpreted_frame()) {
91-
assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
91+
// Test exact placement on top of caller args
92+
intptr_t* l2 = caller->interpreter_frame_last_sp() + caller_actual_parameters - 1;
93+
assert(l2 <= caller->interpreter_frame_expression_stack(), "bad placement");
94+
assert(l2 >= locals, "bad placement");
9295
}
9396
#endif
9497

src/hotspot/share/interpreter/bytecode.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ class Bytecode_invoke: public Bytecode_member_ref {
226226

227227
bool has_appendix();
228228

229+
bool has_member_arg() const;
230+
229231
int size_of_parameters() const;
230232

231233
private:

src/hotspot/share/interpreter/bytecode.inline.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "interpreter/bytecode.hpp"
2929

3030
#include "oops/cpCache.inline.hpp"
31+
#include "prims/methodHandles.hpp"
3132

3233
inline bool Bytecode_invoke::has_appendix() {
3334
if (invoke_code() == Bytecodes::_invokedynamic) {
@@ -37,4 +38,13 @@ inline bool Bytecode_invoke::has_appendix() {
3738
}
3839
}
3940

41+
inline bool Bytecode_invoke::has_member_arg() const {
42+
// NOTE: We could resolve the call and use the resolved adapter method here, but this function
43+
// is used by deoptimization, where resolving could lead to problems, so we avoid that here
44+
// by doing things symbolically.
45+
//
46+
// invokedynamic instructions don't have a class but obviously don't have a MemberName appendix.
47+
return !is_invokedynamic() && MethodHandles::has_member_arg(klass(), name());
48+
}
49+
4050
#endif // SHARE_INTERPRETER_BYTECODE_INLINE_HPP

src/hotspot/share/runtime/deoptimization.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "gc/shared/collectedHeap.hpp"
3838
#include "gc/shared/memAllocator.hpp"
3939
#include "interpreter/bytecode.hpp"
40+
#include "interpreter/bytecode.inline.hpp"
4041
#include "interpreter/bytecodeStream.hpp"
4142
#include "interpreter/interpreter.hpp"
4243
#include "interpreter/oopMapCache.hpp"
@@ -642,11 +643,12 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
642643
bool caller_was_method_handle = false;
643644
if (deopt_sender.is_interpreted_frame()) {
644645
methodHandle method(current, deopt_sender.interpreter_frame_method());
645-
Bytecode_invoke cur = Bytecode_invoke_check(method, deopt_sender.interpreter_frame_bci());
646-
if (cur.is_invokedynamic() || cur.is_invokehandle()) {
647-
// Method handle invokes may involve fairly arbitrary chains of
648-
// calls so it's impossible to know how much actual space the
649-
// caller has for locals.
646+
Bytecode_invoke cur(method, deopt_sender.interpreter_frame_bci());
647+
if (cur.has_member_arg()) {
648+
// This should cover all real-world cases. One exception is a pathological chain of
649+
// MH.linkToXXX() linker calls, which only trusted code could do anyway. To handle that case, we
650+
// would need to get the size from the resolved method entry. Another exception would
651+
// be an invokedynamic with an adapter that is really a MethodHandle linker.
650652
caller_was_method_handle = true;
651653
}
652654
}
@@ -749,9 +751,14 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
749751
}
750752
#endif
751753

754+
int caller_actual_parameters = -1; // value not used except for interpreted frames, see below
755+
if (deopt_sender.is_interpreted_frame()) {
756+
caller_actual_parameters = callee_parameters + (caller_was_method_handle ? 1 : 0);
757+
}
758+
752759
UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
753760
caller_adjustment * BytesPerWord,
754-
caller_was_method_handle ? 0 : callee_parameters,
761+
caller_actual_parameters,
755762
number_of_frames,
756763
frame_sizes,
757764
frame_pcs,
@@ -940,7 +947,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
940947
if (Bytecodes::is_invoke(cur_code)) {
941948
Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci());
942949
cur_invoke_parameter_size = invoke.size_of_parameters();
943-
if (i != 0 && !invoke.is_invokedynamic() && MethodHandles::has_member_arg(invoke.klass(), invoke.name())) {
950+
if (i != 0 && invoke.has_member_arg()) {
944951
callee_size_of_parameters++;
945952
}
946953
}

src/hotspot/share/runtime/vframeArray.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "classfile/vmSymbols.hpp"
2727
#include "code/vmreg.inline.hpp"
2828
#include "interpreter/bytecode.hpp"
29+
#include "interpreter/bytecode.inline.hpp"
2930
#include "interpreter/interpreter.hpp"
3031
#include "memory/allocation.inline.hpp"
3132
#include "memory/resourceArea.hpp"
@@ -614,10 +615,7 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller
614615
methodHandle caller(current, elem->method());
615616
methodHandle callee(current, element(index - 1)->method());
616617
Bytecode_invoke inv(caller, elem->bci());
617-
// invokedynamic instructions don't have a class but obviously don't have a MemberName appendix.
618-
// NOTE: Use machinery here that avoids resolving of any kind.
619-
const bool has_member_arg =
620-
!inv.is_invokedynamic() && MethodHandles::has_member_arg(inv.klass(), inv.name());
618+
const bool has_member_arg = inv.has_member_arg();
621619
callee_parameters = callee->size_of_parameters() + (has_member_arg ? 1 : 0);
622620
callee_locals = callee->max_locals();
623621
}

0 commit comments

Comments
 (0)