diff --git a/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp index 9470caae9fe..5f65ef5f043 100644 --- a/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,16 +41,17 @@ enum { // registers enum { + pd_nof_available_regs = 32, pd_nof_cpu_regs_frame_map = Register::number_of_registers, // number of GP registers used during code emission pd_nof_fpu_regs_frame_map = FloatRegister::number_of_registers, // number of FP registers used during code emission - pd_nof_caller_save_cpu_regs_frame_map = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), // number of registers killed by calls + pd_nof_caller_save_cpu_regs_frame_map = pd_nof_available_regs, // number of registers killed by calls pd_nof_caller_save_fpu_regs_frame_map = 32, // number of registers killed by calls - pd_first_callee_saved_reg = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), - pd_last_callee_saved_reg = 26 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), + pd_first_callee_saved_reg = pd_nof_available_regs - 1, + pd_last_callee_saved_reg = pd_first_callee_saved_reg - 1, // in fact, no callee saved regs - pd_last_allocatable_cpu_reg = 16 R18_RESERVED_ONLY(- 1), + pd_last_allocatable_cpu_reg = pd_nof_available_regs - 1, pd_nof_cpu_regs_reg_alloc = pd_last_allocatable_cpu_reg + 1, // number of registers that are visible to register allocator @@ -60,9 +61,9 @@ enum { pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of registers visible to linear scan pd_nof_xmm_regs_linearscan = 0, // don't have vector registers pd_first_cpu_reg = 0, - pd_last_cpu_reg = 16 R18_RESERVED_ONLY(- 1), + pd_last_cpu_reg = pd_nof_available_regs - 1, pd_first_byte_reg = 0, - pd_last_byte_reg = 16 R18_RESERVED_ONLY(- 1), + pd_last_byte_reg = pd_last_cpu_reg, pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, pd_last_fpu_reg = pd_first_fpu_reg + 31, diff --git a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp index 051b2ff47c1..9d30092b45a 100644 --- a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp @@ -193,9 +193,26 @@ void FrameMap::initialize() { map_register(i, r25); r25_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r26); r26_opr = LIR_OprFact::single_cpu(i); i++; - map_register(i, r27); r27_opr = LIR_OprFact::single_cpu(i); i++; // rheapbase + // r27 is allocated conditionally. With compressed oops it holds + // the heapbase value and is not visible to the allocator. + bool preserve_rheapbase = i >= nof_caller_save_cpu_regs(); + if (!preserve_rheapbase) { + map_register(i, r27); r27_opr = LIR_OprFact::single_cpu(i); i++; // rheapbase + } + + if(!PreserveFramePointer) { + map_register(i, r29); r29_opr = LIR_OprFact::single_cpu(i); i++; + } + + // The unallocatable registers are at the end + + if (preserve_rheapbase) { + map_register(i, r27); r27_opr = LIR_OprFact::single_cpu(i); i++; // rheapbase + } map_register(i, r28); r28_opr = LIR_OprFact::single_cpu(i); i++; // rthread - map_register(i, r29); r29_opr = LIR_OprFact::single_cpu(i); i++; // rfp + if(PreserveFramePointer) { + map_register(i, r29); r29_opr = LIR_OprFact::single_cpu(i); i++; // rfp + } map_register(i, r30); r30_opr = LIR_OprFact::single_cpu(i); i++; // lr map_register(i, r31_sp); sp_opr = LIR_OprFact::single_cpu(i); i++; // sp map_register(i, r8); r8_opr = LIR_OprFact::single_cpu(i); i++; // rscratch1 @@ -239,6 +256,19 @@ void FrameMap::initialize() { _caller_save_cpu_regs[16] = r18_opr; #endif + _caller_save_cpu_regs[17 R18_RESERVED_ONLY(-1)] = r19_opr; + _caller_save_cpu_regs[18 R18_RESERVED_ONLY(-1)] = r20_opr; + _caller_save_cpu_regs[19 R18_RESERVED_ONLY(-1)] = r21_opr; + _caller_save_cpu_regs[20 R18_RESERVED_ONLY(-1)] = r22_opr; + _caller_save_cpu_regs[21 R18_RESERVED_ONLY(-1)] = r23_opr; + _caller_save_cpu_regs[22 R18_RESERVED_ONLY(-1)] = r24_opr; + _caller_save_cpu_regs[23 R18_RESERVED_ONLY(-1)] = r25_opr; + _caller_save_cpu_regs[24 R18_RESERVED_ONLY(-1)] = r26_opr; + + if (nof_caller_save_cpu_regs() > 25 R18_RESERVED_ONLY(-1)) { + _caller_save_cpu_regs[25 R18_RESERVED_ONLY(-1)] = r27_opr; + } + for (int i = 0; i < 8; i++) { _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); } diff --git a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.hpp index 3ec3ce1f679..4d783418429 100644 --- a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -140,8 +140,27 @@ static bool is_caller_save_register (LIR_Opr opr) { return true; } static bool is_caller_save_register (Register r) { return true; } - static int nof_caller_save_cpu_regs() { return pd_nof_caller_save_cpu_regs_frame_map; } - static int last_cpu_reg() { return pd_last_cpu_reg; } - static int last_byte_reg() { return pd_last_byte_reg; } + static int adjust_reg_range(int range, bool exclude_fp = true) { + // r27 is not allocatable when compressed oops is on and heapbase is not + // zero, compressed klass pointers doesn't use r27 after JDK-8234794 + if (UseCompressedOops && (CompressedOops::base() != nullptr)) { + range -= 1; + } + + // r29 is not allocatable when PreserveFramePointer is on, + // but fp saving is handled in MacroAssembler::build_frame()/remove_frame() + if (exclude_fp) { + range -= 1; + } + + // rscratch registers r8, r9 + // r28=rthread, r30=lr, r31=sp + // r18 on masOS/Windows + return range - 5 R18_RESERVED_ONLY(-1); + } + + static int nof_caller_save_cpu_regs() { return adjust_reg_range(pd_nof_caller_save_cpu_regs_frame_map); } + static int last_cpu_reg() { return adjust_reg_range(pd_last_cpu_reg, PreserveFramePointer); } + static int last_byte_reg() { return adjust_reg_range(pd_last_byte_reg, PreserveFramePointer); } #endif // CPU_AARCH64_C1_FRAMEMAP_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.hpp index 01a4d27532a..4062adf4154 100644 --- a/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,9 +41,9 @@ inline bool LinearScan::requires_adjacent_regs(BasicType type) { inline bool LinearScan::is_caller_save(int assigned_reg) { assert(assigned_reg >= 0 && assigned_reg < nof_regs, "should call this only for registers"); - if (assigned_reg < pd_first_callee_saved_reg) + if (assigned_reg < FrameMap::nof_caller_save_cpu_regs()) return true; - if (assigned_reg > pd_last_callee_saved_reg && assigned_reg < pd_first_callee_saved_fpu_reg) + if (assigned_reg >= pd_first_fpu_reg && assigned_reg < pd_first_callee_saved_fpu_reg) return true; if (assigned_reg > pd_last_callee_saved_fpu_reg && assigned_reg < pd_last_fpu_reg) return true; @@ -66,7 +66,7 @@ inline bool LinearScanWalker::pd_init_regs_for_alloc(Interval* cur) { return true; } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT || cur->type() == T_ADDRESS || cur->type() == T_METADATA) { _first_reg = pd_first_cpu_reg; - _last_reg = pd_last_allocatable_cpu_reg; + _last_reg = FrameMap::last_cpu_reg(); return true; } return false; diff --git a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp index 7082b4110cd..063918ee20b 100644 --- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp @@ -257,15 +257,18 @@ static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) { int frame_size_in_slots = frame_size_in_bytes / sizeof(jint); OopMap* oop_map = new OopMap(frame_size_in_slots, 0); - for (int i = 0; i < FrameMap::nof_cpu_regs; i++) { - Register r = as_Register(i); - if (r == rthread || (i <= 18 && i != rscratch1->encoding() && i != rscratch2->encoding())) { - int sp_offset = cpu_reg_save_offsets[i]; - oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset), - r->as_VMReg()); - } + for (int i = 0; i < FrameMap::nof_caller_save_cpu_regs(); i++) { + LIR_Opr opr = FrameMap::caller_save_cpu_reg_at(i); + Register r = opr->as_register(); + int reg_num = r->encoding(); + int sp_offset = cpu_reg_save_offsets[reg_num]; + oop_map->set_callee_saved(VMRegImpl::stack2reg(cpu_reg_save_offsets[reg_num]), r->as_VMReg()); } + Register r = rthread; + int reg_num = r->encoding(); + oop_map->set_callee_saved(VMRegImpl::stack2reg(cpu_reg_save_offsets[reg_num]), r->as_VMReg()); + if (save_fpu_registers) { for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { FloatRegister r = as_FloatRegister(i); diff --git a/src/hotspot/share/c1/c1_Compiler.cpp b/src/hotspot/share/c1/c1_Compiler.cpp index 7d2e6ee75d9..a26320589c4 100644 --- a/src/hotspot/share/c1/c1_Compiler.cpp +++ b/src/hotspot/share/c1/c1_Compiler.cpp @@ -49,8 +49,8 @@ Compiler::Compiler() : AbstractCompiler(compiler_c1) { void Compiler::init_c1_runtime() { BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); - Runtime1::initialize(buffer_blob); FrameMap::initialize(); + Runtime1::initialize(buffer_blob); // initialize data structures ValueType::initialize(); GraphBuilder::initialize(); diff --git a/src/hotspot/share/c1/c1_FrameMap.hpp b/src/hotspot/share/c1/c1_FrameMap.hpp index 1fd7dd3edff..dab3aa6e734 100644 --- a/src/hotspot/share/c1/c1_FrameMap.hpp +++ b/src/hotspot/share/c1/c1_FrameMap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ #include "runtime/frame.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" +#include "oops/compressedOops.hpp" class ciMethod; class CallingConvention;