Skip to content

Commit 3e3822a

Browse files
ruben-armTheRealMDoerr
authored andcommitted
8365047: Remove exception handler stub code in C2
Co-authored-by: Martin Doerr <mdoerr@openjdk.org> Reviewed-by: mdoerr, dlong, dfenacci, adinn, fyang, aph
1 parent 6a51b51 commit 3e3822a

Some content is hidden

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

41 files changed

+353
-301
lines changed

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//
22
// Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
33
// Copyright (c) 2014, 2024, Red Hat, Inc. All rights reserved.
4+
// Copyright 2025 Arm Limited and/or its affiliates.
45
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
56
//
67
// This code is free software; you can redistribute it and/or modify it
@@ -1194,15 +1195,10 @@ class HandlerImpl {
11941195

11951196
public:
11961197

1197-
static int emit_exception_handler(C2_MacroAssembler *masm);
11981198
static int emit_deopt_handler(C2_MacroAssembler* masm);
11991199

1200-
static uint size_exception_handler() {
1201-
return MacroAssembler::far_codestub_branch_size();
1202-
}
1203-
12041200
static uint size_deopt_handler() {
1205-
// count one adr and one far branch instruction
1201+
// count one branch instruction and one far call instruction sequence
12061202
return NativeInstruction::instruction_size + MacroAssembler::far_codestub_branch_size();
12071203
}
12081204
};
@@ -2261,25 +2257,6 @@ uint MachUEPNode::size(PhaseRegAlloc* ra_) const
22612257

22622258
//=============================================================================
22632259

2264-
// Emit exception handler code.
2265-
int HandlerImpl::emit_exception_handler(C2_MacroAssembler* masm)
2266-
{
2267-
// mov rscratch1 #exception_blob_entry_point
2268-
// br rscratch1
2269-
// Note that the code buffer's insts_mark is always relative to insts.
2270-
// That's why we must use the macroassembler to generate a handler.
2271-
address base = __ start_a_stub(size_exception_handler());
2272-
if (base == nullptr) {
2273-
ciEnv::current()->record_failure("CodeCache is full");
2274-
return 0; // CodeBuffer::expand failed
2275-
}
2276-
int offset = __ offset();
2277-
__ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
2278-
assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
2279-
__ end_a_stub();
2280-
return offset;
2281-
}
2282-
22832260
// Emit deopt handler code.
22842261
int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm)
22852262
{
@@ -2290,14 +2267,18 @@ int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm)
22902267
ciEnv::current()->record_failure("CodeCache is full");
22912268
return 0; // CodeBuffer::expand failed
22922269
}
2270+
22932271
int offset = __ offset();
2272+
Label start;
2273+
__ bind(start);
2274+
__ far_call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
22942275

2295-
__ adr(lr, __ pc());
2296-
__ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
2276+
int entry_offset = __ offset();
2277+
__ b(start);
22972278

22982279
assert(__ offset() - offset == (int) size_deopt_handler(), "overflow");
22992280
__ end_a_stub();
2300-
return offset;
2281+
return entry_offset;
23012282
}
23022283

23032284
// REQUIRED MATCHER CODE

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,12 +449,18 @@ int LIR_Assembler::emit_deopt_handler() {
449449

450450
int offset = code_offset();
451451

452-
__ adr(lr, pc());
453-
__ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
452+
Label start;
453+
__ bind(start);
454+
455+
__ far_call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
456+
457+
int entry_offset = __ offset();
458+
__ b(start);
459+
454460
guarantee(code_offset() - offset <= deopt_handler_size(), "overflow");
455461
__ end_a_stub();
456462

457-
return offset;
463+
return entry_offset;
458464
}
459465

460466
void LIR_Assembler::add_debug_info_for_branch(address adr, CodeEmitInfo* info) {

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ friend class ArrayCopyStub;
7171
// CompiledDirectCall::to_trampoline_stub_size()
7272
_call_stub_size = 13 * NativeInstruction::instruction_size,
7373
_exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175),
74-
_deopt_handler_size = 7 * NativeInstruction::instruction_size
74+
_deopt_handler_size = 4 * NativeInstruction::instruction_size
7575
};
7676

7777
public:

src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,6 @@ void NativePostCallNop::make_deopt() {
394394
NativeDeoptInstruction::insert(addr_at(0));
395395
}
396396

397-
#ifdef ASSERT
398-
static bool is_movk_to_zr(uint32_t insn) {
399-
return ((insn & 0xffe0001f) == 0xf280001f);
400-
}
401-
#endif
402-
403397
bool NativePostCallNop::patch(int32_t oopmap_slot, int32_t cb_offset) {
404398
if (((oopmap_slot & 0xff) != oopmap_slot) || ((cb_offset & 0xffffff) != cb_offset)) {
405399
return false; // cannot encode

src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -526,14 +526,24 @@ inline NativeLdSt* NativeLdSt_at(address addr) {
526526
// can store an offset from the initial nop to the nmethod.
527527

528528
class NativePostCallNop: public NativeInstruction {
529+
private:
530+
static bool is_movk_to_zr(uint32_t insn) {
531+
return ((insn & 0xffe0001f) == 0xf280001f);
532+
}
533+
529534
public:
530535
bool check() const {
531-
uint64_t insns = *(uint64_t*)addr_at(0);
532-
// Check for two instructions: nop; movk zr, xx
533-
// These instructions only ever appear together in a post-call
534-
// NOP, so it's unnecessary to check that the third instruction is
535-
// a MOVK as well.
536-
return (insns & 0xffe0001fffffffff) == 0xf280001fd503201f;
536+
// Check the first instruction is NOP.
537+
if (is_nop()) {
538+
uint32_t insn = *(uint32_t*)addr_at(4);
539+
// Check next instruction is MOVK zr, xx.
540+
// These instructions only ever appear together in a post-call
541+
// NOP, so it's unnecessary to check that the third instruction is
542+
// a MOVK as well.
543+
return is_movk_to_zr(insn);
544+
}
545+
546+
return false;
537547
}
538548

539549
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const {

src/hotspot/cpu/aarch64/runtime_aarch64.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,6 @@ UncommonTrapBlob* OptoRuntime::generate_uncommon_trap_blob() {
260260

261261
//------------------------------generate_exception_blob---------------------------
262262
// creates exception blob at the end
263-
// Using exception blob, this code is jumped from a compiled method.
264-
// (see emit_exception_handler in aarch64.ad file)
265263
//
266264
// Given an exception pc at a call we call into the runtime for the
267265
// handler in this method. This handler might merely restore state

src/hotspot/cpu/arm/arm.ad

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,8 @@ class HandlerImpl {
105105

106106
public:
107107

108-
static int emit_exception_handler(C2_MacroAssembler *masm);
109108
static int emit_deopt_handler(C2_MacroAssembler* masm);
110109

111-
static uint size_exception_handler() {
112-
return ( 3 * 4 );
113-
}
114-
115-
116110
static uint size_deopt_handler() {
117111
return ( 9 * 4 );
118112
}
@@ -876,26 +870,6 @@ uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
876870

877871
//=============================================================================
878872

879-
// Emit exception handler code.
880-
int HandlerImpl::emit_exception_handler(C2_MacroAssembler* masm) {
881-
address base = __ start_a_stub(size_exception_handler());
882-
if (base == nullptr) {
883-
ciEnv::current()->record_failure("CodeCache is full");
884-
return 0; // CodeBuffer::expand failed
885-
}
886-
887-
int offset = __ offset();
888-
889-
// OK to trash LR, because exception blob will kill it
890-
__ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, LR_tmp);
891-
892-
assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
893-
894-
__ end_a_stub();
895-
896-
return offset;
897-
}
898-
899873
int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
900874
// Can't use any of the current frame's registers as we may have deopted
901875
// at a poll and everything can be live.
@@ -906,19 +880,26 @@ int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
906880
}
907881

908882
int offset = __ offset();
909-
address deopt_pc = __ pc();
910883

911-
__ sub(SP, SP, wordSize); // make room for saved PC
912-
__ push(LR); // save LR that may be live when we get here
913-
__ mov_relative_address(LR, deopt_pc);
914-
__ str(LR, Address(SP, wordSize)); // save deopt PC
915-
__ pop(LR); // restore LR
884+
Label start;
885+
__ bind(start);
886+
916887
__ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
917888

889+
int entry_offset = __ offset();
890+
address deopt_pc = __ pc();
891+
// Preserve R0 and reserve space for the address of the entry point
892+
__ push(RegisterSet(R0) | RegisterSet(R1));
893+
// Store the entry point address
894+
__ mov_relative_address(R0, deopt_pc);
895+
__ str(R0, Address(SP, wordSize));
896+
__ pop(R0); // restore R0
897+
__ b(start);
898+
918899
assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
919900

920901
__ end_a_stub();
921-
return offset;
902+
return entry_offset;
922903
}
923904

924905
bool Matcher::match_rule_supported(int opcode) {

src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,20 @@ int LIR_Assembler::emit_deopt_handler() {
272272

273273
int offset = code_offset();
274274

275+
Label start;
276+
__ bind(start);
277+
278+
__ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
279+
280+
int entry_offset = __ offset();
275281
__ mov_relative_address(LR, __ pc());
276282
__ push(LR); // stub expects LR to be saved
277-
__ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
283+
__ b(start);
278284

279285
assert(code_offset() - offset <= deopt_handler_size(), "overflow");
280286
__ end_a_stub();
281287

282-
return offset;
288+
return entry_offset;
283289
}
284290

285291

src/hotspot/cpu/arm/c1_LIRAssembler_arm.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
enum {
5555
_call_stub_size = 16,
5656
_exception_handler_size = PRODUCT_ONLY(68) NOT_PRODUCT(68+60),
57-
_deopt_handler_size = 16
57+
_deopt_handler_size = 20
5858
};
5959

6060
public:

src/hotspot/cpu/arm/runtime_arm.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,6 @@ UncommonTrapBlob* OptoRuntime::generate_uncommon_trap_blob() {
182182

183183
//------------------------------ generate_exception_blob ---------------------------
184184
// creates exception blob at the end
185-
// Using exception blob, this code is jumped from a compiled method.
186-
// (see emit_exception_handler in sparc.ad file)
187185
//
188186
// Given an exception pc at a call we call into the runtime for the
189187
// handler in this method. This handler might merely restore state

0 commit comments

Comments
 (0)