Skip to content
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 9 additions & 28 deletions src/hotspot/cpu/aarch64/aarch64.ad
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//
// Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2014, 2024, Red Hat, Inc. All rights reserved.
// Copyright 2025 Arm Limited and/or its affiliates.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -1194,15 +1195,10 @@ class HandlerImpl {

public:

static int emit_exception_handler(C2_MacroAssembler *masm);
static int emit_deopt_handler(C2_MacroAssembler* masm);

static uint size_exception_handler() {
return MacroAssembler::far_codestub_branch_size();
}

static uint size_deopt_handler() {
// count one adr and one far branch instruction
// count one branch instruction and one far call instruction sequence
return NativeInstruction::instruction_size + MacroAssembler::far_codestub_branch_size();
}
};
Expand Down Expand Up @@ -2261,25 +2257,6 @@ uint MachUEPNode::size(PhaseRegAlloc* ra_) const

//=============================================================================

// Emit exception handler code.
int HandlerImpl::emit_exception_handler(C2_MacroAssembler* masm)
{
// mov rscratch1 #exception_blob_entry_point
// br rscratch1
// Note that the code buffer's insts_mark is always relative to insts.
// That's why we must use the macroassembler to generate a handler.
address base = __ start_a_stub(size_exception_handler());
if (base == nullptr) {
ciEnv::current()->record_failure("CodeCache is full");
return 0; // CodeBuffer::expand failed
}
int offset = __ offset();
__ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
__ end_a_stub();
return offset;
}

// Emit deopt handler code.
int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm)
{
Expand All @@ -2290,14 +2267,18 @@ int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm)
ciEnv::current()->record_failure("CodeCache is full");
return 0; // CodeBuffer::expand failed
}

int offset = __ offset();
Label start;
__ bind(start);
__ far_call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));

__ adr(lr, __ pc());
__ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
int entry_offset = __ offset();
__ b(start);

assert(__ offset() - offset == (int) size_deopt_handler(), "overflow");
__ end_a_stub();
return offset;
return entry_offset;
}

// REQUIRED MATCHER CODE
Expand Down
12 changes: 9 additions & 3 deletions src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,18 @@ int LIR_Assembler::emit_deopt_handler() {

int offset = code_offset();

__ adr(lr, pc());
__ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
Label start;
__ bind(start);

__ far_call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));

int entry_offset = __ offset();
__ b(start);

guarantee(code_offset() - offset <= deopt_handler_size(), "overflow");
__ end_a_stub();

return offset;
return entry_offset;
}

void LIR_Assembler::add_debug_info_for_branch(address adr, CodeEmitInfo* info) {
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ friend class ArrayCopyStub;
// CompiledDirectCall::to_trampoline_stub_size()
_call_stub_size = 13 * NativeInstruction::instruction_size,
_exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175),
_deopt_handler_size = 7 * NativeInstruction::instruction_size
_deopt_handler_size = 4 * NativeInstruction::instruction_size
};

public:
Expand Down
6 changes: 0 additions & 6 deletions src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,12 +394,6 @@ void NativePostCallNop::make_deopt() {
NativeDeoptInstruction::insert(addr_at(0));
}

#ifdef ASSERT
static bool is_movk_to_zr(uint32_t insn) {
return ((insn & 0xffe0001f) == 0xf280001f);
}
#endif

bool NativePostCallNop::patch(int32_t oopmap_slot, int32_t cb_offset) {
if (((oopmap_slot & 0xff) != oopmap_slot) || ((cb_offset & 0xffffff) != cb_offset)) {
return false; // cannot encode
Expand Down
22 changes: 16 additions & 6 deletions src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,14 +526,24 @@ inline NativeLdSt* NativeLdSt_at(address addr) {
// can store an offset from the initial nop to the nmethod.

class NativePostCallNop: public NativeInstruction {
private:
static bool is_movk_to_zr(uint32_t insn) {
return ((insn & 0xffe0001f) == 0xf280001f);
}

public:
bool check() const {
uint64_t insns = *(uint64_t*)addr_at(0);
// Check for two instructions: nop; movk zr, xx
// These instructions only ever appear together in a post-call
// NOP, so it's unnecessary to check that the third instruction is
// a MOVK as well.
return (insns & 0xffe0001fffffffff) == 0xf280001fd503201f;
// Check the first instruction is NOP.
if (is_nop()) {
uint32_t insn = *(uint32_t*)addr_at(4);
// Check next instruction is MOVK zr, xx.
// These instructions only ever appear together in a post-call
// NOP, so it's unnecessary to check that the third instruction is
// a MOVK as well.
return is_movk_to_zr(insn);
}

return false;
}

bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const {
Expand Down
2 changes: 0 additions & 2 deletions src/hotspot/cpu/aarch64/runtime_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,6 @@ UncommonTrapBlob* OptoRuntime::generate_uncommon_trap_blob() {

//------------------------------generate_exception_blob---------------------------
// creates exception blob at the end
// Using exception blob, this code is jumped from a compiled method.
// (see emit_exception_handler in aarch64.ad file)
//
// Given an exception pc at a call we call into the runtime for the
// handler in this method. This handler might merely restore state
Expand Down
47 changes: 14 additions & 33 deletions src/hotspot/cpu/arm/arm.ad
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,8 @@ class HandlerImpl {

public:

static int emit_exception_handler(C2_MacroAssembler *masm);
static int emit_deopt_handler(C2_MacroAssembler* masm);

static uint size_exception_handler() {
return ( 3 * 4 );
}


static uint size_deopt_handler() {
return ( 9 * 4 );
}
Expand Down Expand Up @@ -876,26 +870,6 @@ uint MachUEPNode::size(PhaseRegAlloc *ra_) const {

//=============================================================================

// Emit exception handler code.
int HandlerImpl::emit_exception_handler(C2_MacroAssembler* masm) {
address base = __ start_a_stub(size_exception_handler());
if (base == nullptr) {
ciEnv::current()->record_failure("CodeCache is full");
return 0; // CodeBuffer::expand failed
}

int offset = __ offset();

// OK to trash LR, because exception blob will kill it
__ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, LR_tmp);

assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");

__ end_a_stub();

return offset;
}

int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
// Can't use any of the current frame's registers as we may have deopted
// at a poll and everything can be live.
Expand All @@ -906,19 +880,26 @@ int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
}

int offset = __ offset();
address deopt_pc = __ pc();

__ sub(SP, SP, wordSize); // make room for saved PC
__ push(LR); // save LR that may be live when we get here
__ mov_relative_address(LR, deopt_pc);
__ str(LR, Address(SP, wordSize)); // save deopt PC
__ pop(LR); // restore LR
Label start;
__ bind(start);

__ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);

int entry_offset = __ offset();
address deopt_pc = __ pc();
// Preserve R0 and reserve space for the address of the entry point
__ push(RegisterSet(R0) | RegisterSet(R1));
// Store the entry point address
__ mov_relative_address(R0, deopt_pc);
__ str(R0, Address(SP, wordSize));
__ pop(R0); // restore R0
__ b(start);

assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");

__ end_a_stub();
return offset;
return entry_offset;
}

bool Matcher::match_rule_supported(int opcode) {
Expand Down
10 changes: 8 additions & 2 deletions src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,20 @@ int LIR_Assembler::emit_deopt_handler() {

int offset = code_offset();

Label start;
__ bind(start);

__ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);

int entry_offset = __ offset();
__ mov_relative_address(LR, __ pc());
__ push(LR); // stub expects LR to be saved
__ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
__ b(start);

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

return offset;
return entry_offset;
}


Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/arm/c1_LIRAssembler_arm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
enum {
_call_stub_size = 16,
_exception_handler_size = PRODUCT_ONLY(68) NOT_PRODUCT(68+60),
_deopt_handler_size = 16
_deopt_handler_size = 20
};

public:
Expand Down
2 changes: 0 additions & 2 deletions src/hotspot/cpu/arm/runtime_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,6 @@ UncommonTrapBlob* OptoRuntime::generate_uncommon_trap_blob() {

//------------------------------ generate_exception_blob ---------------------------
// creates exception blob at the end
// Using exception blob, this code is jumped from a compiled method.
// (see emit_exception_handler in sparc.ad file)
//
// Given an exception pc at a call we call into the runtime for the
// handler in this method. This handler might merely restore state
Expand Down
7 changes: 6 additions & 1 deletion src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,17 @@ int LIR_Assembler::emit_deopt_handler() {
}

int offset = code_offset();
Label start;

__ bind(start);
__ bl64_patchable(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type);
int entry_offset = __ offset();
__ b(start);

guarantee(code_offset() - offset <= deopt_handler_size(), "overflow");
__ end_a_stub();

return offset;
return entry_offset;
}


Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ enum {
_static_call_stub_size = 4 * BytesPerInstWord + MacroAssembler::b64_patchable_size, // or smaller
_call_stub_size = _static_call_stub_size + MacroAssembler::trampoline_stub_size, // or smaller
_exception_handler_size = MacroAssembler::b64_patchable_size, // or smaller
_deopt_handler_size = MacroAssembler::bl64_patchable_size
_deopt_handler_size = MacroAssembler::bl64_patchable_size + BytesPerInstWord
};

// '_static_call_stub_size' is only used on ppc (see LIR_Assembler::emit_static_call_stub()
Expand Down
35 changes: 11 additions & 24 deletions src/hotspot/cpu/ppc/ppc.ad
Original file line number Diff line number Diff line change
Expand Up @@ -2088,17 +2088,11 @@ class HandlerImpl {

public:

static int emit_exception_handler(C2_MacroAssembler *masm);
static int emit_deopt_handler(C2_MacroAssembler* masm);

static uint size_exception_handler() {
// The exception_handler is a b64_patchable.
return MacroAssembler::b64_patchable_size;
}

static uint size_deopt_handler() {
// The deopt_handler is a bl64_patchable.
return MacroAssembler::bl64_patchable_size;
return MacroAssembler::bl64_patchable_size + BytesPerInstWord;
}

};
Expand All @@ -2114,22 +2108,6 @@ public:

source %{

int HandlerImpl::emit_exception_handler(C2_MacroAssembler *masm) {
address base = __ start_a_stub(size_exception_handler());
if (base == nullptr) {
ciEnv::current()->record_failure("CodeCache is full");
return 0; // CodeBuffer::expand failed
}

int offset = __ offset();
__ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(),
relocInfo::runtime_call_type);
assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size");
__ end_a_stub();

return offset;
}

// The deopt_handler is like the exception handler, but it calls to
// the deoptimization blob instead of jumping to the exception blob.
int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
Expand All @@ -2140,12 +2118,21 @@ int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
}

int offset = __ offset();

Label start;
__ bind(start);

__ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
relocInfo::runtime_call_type);

int entry_offset = __ offset();

__ b(start);

assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
__ end_a_stub();

return offset;
return entry_offset;
}

//=============================================================================
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/cpu/ppc/runtime_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@

//------------------------------generate_exception_blob---------------------------
// Creates exception blob at the end.
// Using exception blob, this code is jumped from a compiled method.
//
// Given an exception pc at a call we call into the runtime for the
// handler in this method. This handler might merely restore state
Expand Down
Loading