Skip to content

Commit 84965ea

Browse files
fiskTheRealMDoerrshipilevoffamitkumarrobehn
committed
8322630: Remove ICStubs and related safepoints
Co-authored-by: Martin Doerr <mdoerr@openjdk.org> Co-authored-by: Aleksey Shipilev <shade@openjdk.org> Co-authored-by: Amit Kumar <amitkumar@openjdk.org> Co-authored-by: Robbin Ehn <rehn@openjdk.org> Co-authored-by: Aleksei Voitylov <avoitylov@openjdk.org> Reviewed-by: tschatzl, aboldtch, dlong
1 parent 0c2def0 commit 84965ea

File tree

142 files changed

+1027
-3752
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+1027
-3752
lines changed

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,14 +2205,14 @@ void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
22052205
{
22062206
st->print_cr("# MachUEPNode");
22072207
if (UseCompressedClassPointers) {
2208-
st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2209-
if (CompressedKlassPointers::shift() != 0) {
2210-
st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
2211-
}
2208+
st->print_cr("\tldrw rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2209+
st->print_cr("\tldrw r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass");
2210+
st->print_cr("\tcmpw rscratch1, r10");
22122211
} else {
2213-
st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2212+
st->print_cr("\tldr rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2213+
st->print_cr("\tldr r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass");
2214+
st->print_cr("\tcmp rscratch1, r10");
22142215
}
2215-
st->print_cr("\tcmp r0, rscratch1\t # Inline cache check");
22162216
st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
22172217
}
22182218
#endif
@@ -2221,14 +2221,7 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
22212221
{
22222222
// This is the unverified entry point.
22232223
C2_MacroAssembler _masm(&cbuf);
2224-
2225-
__ cmp_klass(j_rarg0, rscratch2, rscratch1);
2226-
Label skip;
2227-
// TODO
2228-
// can we avoid this skip and still use a reloc?
2229-
__ br(Assembler::EQ, skip);
2230-
__ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
2231-
__ bind(skip);
2224+
__ ic_check(InteriorEntryAlignment);
22322225
}
22332226

22342227
uint MachUEPNode::size(PhaseRegAlloc* ra_) const
@@ -3715,7 +3708,7 @@ encode %{
37153708
cbuf.shared_stub_to_interp_for(_method, call - cbuf.insts_begin());
37163709
} else {
37173710
// Emit stub for static call
3718-
address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, call);
3711+
address stub = CompiledDirectCall::emit_to_interp_stub(cbuf, call);
37193712
if (stub == nullptr) {
37203713
ciEnv::current()->record_failure("CodeCache is full");
37213714
return;

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
#endif
5454

5555
NEEDS_CLEANUP // remove this definitions ?
56-
const Register IC_Klass = rscratch2; // where the IC klass is cached
5756
const Register SYNC_header = r0; // synchronization header
5857
const Register SHIFT_count = r0; // where count for shift operations must be
5958

@@ -293,27 +292,7 @@ void LIR_Assembler::osr_entry() {
293292

294293
// inline cache check; done before the frame is built.
295294
int LIR_Assembler::check_icache() {
296-
Register receiver = FrameMap::receiver_opr->as_register();
297-
Register ic_klass = IC_Klass;
298-
int start_offset = __ offset();
299-
__ inline_cache_check(receiver, ic_klass);
300-
301-
// if icache check fails, then jump to runtime routine
302-
// Note: RECEIVER must still contain the receiver!
303-
Label dont;
304-
__ br(Assembler::EQ, dont);
305-
__ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
306-
307-
// We align the verified entry point unless the method body
308-
// (including its inline cache check) will fit in a single 64-byte
309-
// icache line.
310-
if (! method()->is_accessor() || __ offset() - start_offset > 4 * 4) {
311-
// force alignment after the cache check.
312-
__ align(CodeEntryAlignment);
313-
}
314-
315-
__ bind(dont);
316-
return start_offset;
295+
return __ ic_check(CodeEntryAlignment);
317296
}
318297

319298
void LIR_Assembler::clinit_barrier(ciMethod* method) {
@@ -2042,7 +2021,7 @@ void LIR_Assembler::emit_static_call_stub() {
20422021
__ relocate(static_stub_Relocation::spec(call_pc));
20432022
__ emit_static_call_stub();
20442023

2045-
assert(__ offset() - start + CompiledStaticCall::to_trampoline_stub_size()
2024+
assert(__ offset() - start + CompiledDirectCall::to_trampoline_stub_size()
20462025
<= call_stub_size(), "stub too big");
20472026
__ end_a_stub();
20482027
}

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ friend class ArrayCopyStub;
7171
void deoptimize_trap(CodeEmitInfo *info);
7272

7373
enum {
74-
// call stub: CompiledStaticCall::to_interp_stub_size() +
75-
// CompiledStaticCall::to_trampoline_stub_size()
74+
// call stub: CompiledDirectCall::to_interp_stub_size() +
75+
// CompiledDirectCall::to_trampoline_stub_size()
7676
_call_stub_size = 13 * NativeInstruction::instruction_size,
7777
_exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175),
7878
_deopt_handler_size = 7 * NativeInstruction::instruction_size

src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -308,17 +308,6 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1,
308308
verify_oop(obj);
309309
}
310310

311-
312-
void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
313-
verify_oop(receiver);
314-
// explicit null check not needed since load from [klass_offset] causes a trap
315-
// check against inline cache
316-
assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
317-
318-
cmp_klass(receiver, iCache, rscratch1);
319-
}
320-
321-
322311
void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes) {
323312
assert(bang_size_in_bytes >= framesize, "stack bang size incorrect");
324313
// Make sure there is enough stack space for this method's activation.

src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
#include "interpreter/interpreter.hpp"
3939
#include "memory/universe.hpp"
4040
#include "nativeInst_aarch64.hpp"
41-
#include "oops/compiledICHolder.hpp"
4241
#include "oops/oop.inline.hpp"
4342
#include "prims/jvmtiExport.hpp"
4443
#include "register_aarch64.hpp"

src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include "precompiled.hpp"
2727
#include "asm/macroAssembler.inline.hpp"
2828
#include "code/compiledIC.hpp"
29-
#include "code/icBuffer.hpp"
3029
#include "code/nmethod.hpp"
3130
#include "logging/log.hpp"
3231
#include "memory/resourceArea.hpp"
@@ -36,7 +35,7 @@
3635
// ----------------------------------------------------------------------------
3736

3837
#define __ _masm.
39-
address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
38+
address CompiledDirectCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
4039
precond(cbuf.stubs()->start() != badAddress);
4140
precond(cbuf.stubs()->end() != badAddress);
4241

@@ -71,33 +70,26 @@ address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark)
7170
}
7271
#undef __
7372

74-
int CompiledStaticCall::to_interp_stub_size() {
73+
int CompiledDirectCall::to_interp_stub_size() {
7574
return MacroAssembler::static_call_stub_size();
7675
}
7776

78-
int CompiledStaticCall::to_trampoline_stub_size() {
77+
int CompiledDirectCall::to_trampoline_stub_size() {
7978
// Somewhat pessimistically, we count 3 instructions here (although
8079
// there are only two) because we sometimes emit an alignment nop.
8180
// Trampoline stubs are always word aligned.
8281
return MacroAssembler::max_trampoline_stub_size();
8382
}
8483

8584
// Relocation entries for call stub, compiled java to interpreter.
86-
int CompiledStaticCall::reloc_to_interp_stub() {
85+
int CompiledDirectCall::reloc_to_interp_stub() {
8786
return 4; // 3 in emit_to_interp_stub + 1 in emit_call
8887
}
8988

90-
void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, address entry) {
89+
void CompiledDirectCall::set_to_interpreted(const methodHandle& callee, address entry) {
9190
address stub = find_stub();
9291
guarantee(stub != nullptr, "stub not found");
9392

94-
{
95-
ResourceMark rm;
96-
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
97-
p2i(instruction_address()),
98-
callee->name_and_sig_as_C_string());
99-
}
100-
10193
// Creation also verifies the object.
10294
NativeMovConstReg* method_holder
10395
= nativeMovConstReg_at(stub + NativeInstruction::instruction_size);
@@ -115,7 +107,7 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
115107
set_destination_mt_safe(stub);
116108
}
117109

118-
void CompiledDirectStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) {
110+
void CompiledDirectCall::set_stub_to_clean(static_stub_Relocation* static_stub) {
119111
// Reset stub.
120112
address stub = static_stub->addr();
121113
assert(stub != nullptr, "stub not found");
@@ -132,7 +124,7 @@ void CompiledDirectStaticCall::set_stub_to_clean(static_stub_Relocation* static_
132124
// Non-product mode code
133125
#ifndef PRODUCT
134126

135-
void CompiledDirectStaticCall::verify() {
127+
void CompiledDirectCall::verify() {
136128
// Verify call.
137129
_call->verify();
138130
_call->verify_alignment();

src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp

Lines changed: 0 additions & 82 deletions
This file was deleted.

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "asm/assembler.hpp"
3030
#include "asm/assembler.inline.hpp"
3131
#include "ci/ciEnv.hpp"
32+
#include "code/compiledIC.hpp"
3233
#include "compiler/compileTask.hpp"
3334
#include "compiler/disassembler.hpp"
3435
#include "compiler/oopMap.hpp"
@@ -965,7 +966,7 @@ int MacroAssembler::max_trampoline_stub_size() {
965966
}
966967

967968
void MacroAssembler::emit_static_call_stub() {
968-
// CompiledDirectStaticCall::set_to_interpreted knows the
969+
// CompiledDirectCall::set_to_interpreted knows the
969970
// exact layout of this stub.
970971

971972
isb();
@@ -995,10 +996,51 @@ address MacroAssembler::ic_call(address entry, jint method_index) {
995996
// address const_ptr = long_constant((jlong)Universe::non_oop_word());
996997
// uintptr_t offset;
997998
// ldr_constant(rscratch2, const_ptr);
998-
movptr(rscratch2, (uintptr_t)Universe::non_oop_word());
999+
movptr(rscratch2, (intptr_t)Universe::non_oop_word());
9991000
return trampoline_call(Address(entry, rh));
10001001
}
10011002

1003+
int MacroAssembler::ic_check_size() {
1004+
if (target_needs_far_branch(CAST_FROM_FN_PTR(address, SharedRuntime::get_ic_miss_stub()))) {
1005+
return NativeInstruction::instruction_size * 7;
1006+
} else {
1007+
return NativeInstruction::instruction_size * 5;
1008+
}
1009+
}
1010+
1011+
int MacroAssembler::ic_check(int end_alignment) {
1012+
Register receiver = j_rarg0;
1013+
Register data = rscratch2;
1014+
Register tmp1 = rscratch1;
1015+
Register tmp2 = r10;
1016+
1017+
// The UEP of a code blob ensures that the VEP is padded. However, the padding of the UEP is placed
1018+
// before the inline cache check, so we don't have to execute any nop instructions when dispatching
1019+
// through the UEP, yet we can ensure that the VEP is aligned appropriately. That's why we align
1020+
// before the inline cache check here, and not after
1021+
align(end_alignment, offset() + ic_check_size());
1022+
1023+
int uep_offset = offset();
1024+
1025+
if (UseCompressedClassPointers) {
1026+
ldrw(tmp1, Address(receiver, oopDesc::klass_offset_in_bytes()));
1027+
ldrw(tmp2, Address(data, CompiledICData::speculated_klass_offset()));
1028+
cmpw(tmp1, tmp2);
1029+
} else {
1030+
ldr(tmp1, Address(receiver, oopDesc::klass_offset_in_bytes()));
1031+
ldr(tmp2, Address(data, CompiledICData::speculated_klass_offset()));
1032+
cmp(tmp1, tmp2);
1033+
}
1034+
1035+
Label dont;
1036+
br(Assembler::EQ, dont);
1037+
far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1038+
bind(dont);
1039+
assert((offset() % end_alignment) == 0, "Misaligned verified entry point");
1040+
1041+
return uep_offset;
1042+
}
1043+
10021044
// Implementation of call_VM versions
10031045

10041046
void MacroAssembler::call_VM(Register oop_result,
@@ -1100,7 +1142,14 @@ void MacroAssembler::get_vm_result_2(Register metadata_result, Register java_thr
11001142
}
11011143

11021144
void MacroAssembler::align(int modulus) {
1103-
while (offset() % modulus != 0) nop();
1145+
align(modulus, offset());
1146+
}
1147+
1148+
// Ensure that the code at target bytes offset from the current offset() is aligned
1149+
// according to modulus.
1150+
void MacroAssembler::align(int modulus, int target) {
1151+
int delta = target - offset();
1152+
while ((offset() + delta) % modulus != 0) nop();
11041153
}
11051154

11061155
void MacroAssembler::post_call_nop() {
@@ -1197,7 +1246,7 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
11971246
}
11981247

11991248
// Look up the method for a megamorphic invokeinterface call in a single pass over itable:
1200-
// - check recv_klass (actual object class) is a subtype of resolved_klass from CompiledICHolder
1249+
// - check recv_klass (actual object class) is a subtype of resolved_klass from CompiledICData
12011250
// - find a holder_klass (class that implements the method) vtable offset and get the method from vtable by index
12021251
// The target method is determined by <holder_klass, itable_index>.
12031252
// The receiver klass is in recv_klass.

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,7 @@ class MacroAssembler: public Assembler {
720720

721721
// Alignment
722722
void align(int modulus);
723+
void align(int modulus, int target);
723724

724725
// nop
725726
void post_call_nop();
@@ -1247,6 +1248,8 @@ class MacroAssembler: public Assembler {
12471248

12481249
// Emit the CompiledIC call idiom
12491250
address ic_call(address entry, jint method_index = 0);
1251+
static int ic_check_size();
1252+
int ic_check(int end_alignment);
12501253

12511254
public:
12521255

0 commit comments

Comments
 (0)