diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 311a9ca046b..18904dd0cfd 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -128,8 +128,8 @@ reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); -reg_def R27 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase -reg_def R27_H ( NS, SOE, Op_RegI, 27, r27->as_VMReg()->next()); +reg_def R27 ( SOC, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase +reg_def R27_H ( SOC, SOE, Op_RegI, 27, r27->as_VMReg()->next()); reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp @@ -435,9 +435,8 @@ alloc_class chunk2(RFLAGS); // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) // -// Class for all 32 bit integer registers -- excludes SP which will -// never be used as an integer register -reg_class any_reg32( +// Class for all 32 bit general purpose registers +reg_class all_reg32( R0, R1, R2, @@ -466,9 +465,17 @@ reg_class any_reg32( R27, R28, R29, - R30 + R30, + R31 ); + +// Class for all 32 bit integer registers (excluding SP which +// will never be used as an integer register) +reg_class any_reg32 %{ + return _ANY_REG32_mask; +%} + // Singleton class for R0 int register reg_class int_r0_reg(R0); @@ -481,8 +488,11 @@ reg_class int_r3_reg(R3); // Singleton class for R4 int register reg_class int_r4_reg(R4); -// Class for all long integer registers (including RSP) -reg_class any_reg( +// Singleton class for R31 int register +reg_class int_r31_reg(R31); + +// Class for all 64 bit general purpose registers +reg_class all_reg( R0, R0_H, R1, R1_H, R2, R2_H, @@ -515,143 +525,34 @@ reg_class any_reg( R31, R31_H ); -// Class for all non-special integer registers -reg_class no_special_reg32_no_fp( - R0, - R1, - R2, - R3, - R4, - R5, - R6, - R7, - R10, - R11, - R12, // rmethod - R13, - R14, - R15, - R16, - R17, - R18, - R19, - R20, - R21, - R22, - R23, - R24, - R25, - R26 - /* R27, */ // heapbase - /* R28, */ // thread - /* R29, */ // fp - /* R30, */ // lr - /* R31 */ // sp -); +// Class for all long integer registers (including SP) +reg_class any_reg %{ + return _ANY_REG_mask; +%} -reg_class no_special_reg32_with_fp( - R0, - R1, - R2, - R3, - R4, - R5, - R6, - R7, - R10, - R11, - R12, // rmethod - R13, - R14, - R15, - R16, - R17, - R18, - R19, - R20, - R21, - R22, - R23, - R24, - R25, - R26 - /* R27, */ // heapbase - /* R28, */ // thread - R29, // fp - /* R30, */ // lr - /* R31 */ // sp +// Class for non-allocatable 32 bit registers +reg_class non_allocatable_reg32( + R28, // thread + R30, // lr + R31 // sp ); -reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %}); - -// Class for all non-special long integer registers -reg_class no_special_reg_no_fp( - R0, R0_H, - R1, R1_H, - R2, R2_H, - R3, R3_H, - R4, R4_H, - R5, R5_H, - R6, R6_H, - R7, R7_H, - R10, R10_H, - R11, R11_H, - R12, R12_H, // rmethod - R13, R13_H, - R14, R14_H, - R15, R15_H, - R16, R16_H, - R17, R17_H, - R18, R18_H, - R19, R19_H, - R20, R20_H, - R21, R21_H, - R22, R22_H, - R23, R23_H, - R24, R24_H, - R25, R25_H, - R26, R26_H, - /* R27, R27_H, */ // heapbase - /* R28, R28_H, */ // thread - /* R29, R29_H, */ // fp - /* R30, R30_H, */ // lr - /* R31, R31_H */ // sp +// Class for non-allocatable 64 bit registers +reg_class non_allocatable_reg( + R28, R28_H, // thread + R30, R30_H, // lr + R31, R31_H // sp ); -reg_class no_special_reg_with_fp( - R0, R0_H, - R1, R1_H, - R2, R2_H, - R3, R3_H, - R4, R4_H, - R5, R5_H, - R6, R6_H, - R7, R7_H, - R10, R10_H, - R11, R11_H, - R12, R12_H, // rmethod - R13, R13_H, - R14, R14_H, - R15, R15_H, - R16, R16_H, - R17, R17_H, - R18, R18_H, - R19, R19_H, - R20, R20_H, - R21, R21_H, - R22, R22_H, - R23, R23_H, - R24, R24_H, - R25, R25_H, - R26, R26_H, - /* R27, R27_H, */ // heapbase - /* R28, R28_H, */ // thread - R29, R29_H, // fp - /* R30, R30_H, */ // lr - /* R31, R31_H */ // sp -); +// Class for all non-special integer registers +reg_class no_special_reg32 %{ + return _NO_SPECIAL_REG32_mask; +%} -reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %}); +// Class for all non-special long integer registers +reg_class no_special_reg %{ + return _NO_SPECIAL_REG_mask; +%} // Class for 64 bit register r0 reg_class r0_reg( @@ -724,72 +625,14 @@ reg_class sp_reg( ); // Class for all pointer registers -reg_class ptr_reg( - R0, R0_H, - R1, R1_H, - R2, R2_H, - R3, R3_H, - R4, R4_H, - R5, R5_H, - R6, R6_H, - R7, R7_H, - R10, R10_H, - R11, R11_H, - R12, R12_H, - R13, R13_H, - R14, R14_H, - R15, R15_H, - R16, R16_H, - R17, R17_H, - R18, R18_H, - R19, R19_H, - R20, R20_H, - R21, R21_H, - R22, R22_H, - R23, R23_H, - R24, R24_H, - R25, R25_H, - R26, R26_H, - R27, R27_H, - R28, R28_H, - R29, R29_H, - R30, R30_H, - R31, R31_H -); +reg_class ptr_reg %{ + return _PTR_REG_mask; +%} // Class for all non_special pointer registers -reg_class no_special_ptr_reg( - R0, R0_H, - R1, R1_H, - R2, R2_H, - R3, R3_H, - R4, R4_H, - R5, R5_H, - R6, R6_H, - R7, R7_H, - R10, R10_H, - R11, R11_H, - R12, R12_H, - R13, R13_H, - R14, R14_H, - R15, R15_H, - R16, R16_H, - R17, R17_H, - R18, R18_H, - R19, R19_H, - R20, R20_H, - R21, R21_H, - R22, R22_H, - R23, R23_H, - R24, R24_H, - R25, R25_H, - R26, R26_H, - /* R27, R27_H, */ // heapbase - /* R28, R28_H, */ // thread - /* R29, R29_H, */ // fp - /* R30, R30_H, */ // lr - /* R31, R31_H */ // sp -); +reg_class no_special_ptr_reg %{ + return _NO_SPECIAL_PTR_REG_mask; +%} // Class for all float registers reg_class float_reg( @@ -1002,6 +845,13 @@ source_hpp %{ #include "gc/shared/collectedHeap.hpp" #include "opto/addnode.hpp" +extern RegMask _ANY_REG32_mask; +extern RegMask _ANY_REG_mask; +extern RegMask _PTR_REG_mask; +extern RegMask _NO_SPECIAL_REG32_mask; +extern RegMask _NO_SPECIAL_REG_mask; +extern RegMask _NO_SPECIAL_PTR_REG_mask; + class CallStubImpl { //-------------------------------------------------------------- @@ -1062,6 +912,52 @@ class HandlerImpl { source %{ + // Derived RegMask with conditionally allocatable registers + + RegMask _ANY_REG32_mask; + RegMask _ANY_REG_mask; + RegMask _PTR_REG_mask; + RegMask _NO_SPECIAL_REG32_mask; + RegMask _NO_SPECIAL_REG_mask; + RegMask _NO_SPECIAL_PTR_REG_mask; + + void reg_mask_init() { + // We derive below RegMask(s) from the ones which are auto-generated from + // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29) + // registers conditionally reserved. + + _ANY_REG32_mask = _ALL_REG32_mask; + _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg())); + + _ANY_REG_mask = _ALL_REG_mask; + + _PTR_REG_mask = _ALL_REG_mask; + + _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; + _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); + + _NO_SPECIAL_REG_mask = _ALL_REG_mask; + _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); + + _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; + _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); + + // 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 && (Universe::narrow_ptrs_base() != NULL || UseAOT)) { + _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); + _NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); + _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); + } + + // r29 is not allocatable when PreserveFramePointer is on + if (PreserveFramePointer) { + _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); + _NO_SPECIAL_REG_mask.SUBTRACT(_FP_REG_mask); + _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_FP_REG_mask); + } + } + // Optimizaton of volatile gets and puts // ------------------------------------- // @@ -7023,19 +6919,17 @@ instruct storeN(iRegN src, memory mem) ins_pipe(istore_reg_mem); %} -instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) +instruct storeImmN0(immN0 zero, memory mem) %{ match(Set mem (StoreN mem zero)); - predicate(Universe::narrow_oop_base() == NULL && - Universe::narrow_klass_base() == NULL && - (!needs_releasing_store(n))); + predicate(!needs_releasing_store(n)); ins_cost(INSN_COST); - format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} + format %{ "strw zr, $mem\t# compressed ptr" %} - ins_encode(aarch64_enc_strw(heapbase, mem)); + ins_encode(aarch64_enc_strw0(mem)); - ins_pipe(istore_reg_mem); + ins_pipe(istore_mem); %} // Store Float diff --git a/src/hotspot/cpu/aarch64/c2_init_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_init_aarch64.cpp index 1f3877cf5e3..436e0c5e41c 100644 --- a/src/hotspot/cpu/aarch64/c2_init_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_init_aarch64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Red Hat Inc. 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 @@ -27,10 +27,11 @@ #include "opto/compile.hpp" #include "opto/node.hpp" -// processor dependent initialization for i486 +// processor dependent initialization for AArch64 + +extern void reg_mask_init(); void Compile::pd_compiler2_init() { guarantee(CodeEntryAlignment >= InteriorEntryAlignment, "" ); - // QQQ presumably all 64bit cpu's support this. Seems like the ifdef could - // simply be left out. + reg_mask_init(); } diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 6429b9dde09..00a88dd36a6 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -2113,6 +2113,10 @@ void MacroAssembler::verify_heapbase(const char* msg) { #if 0 assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed"); assert (Universe::heap() != NULL, "java heap should be initialized"); + if (!UseCompressedOops || Universe::ptr_base() == NULL) { + // rheapbase is allocated as general register + return; + } if (CheckCompressedOops) { Label ok; push(1 << rscratch1->encoding(), sp); // cmpptr trashes rscratch1 diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 3d3cc3a1e06..614e6d71d6a 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -146,7 +146,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ for (int i = 0; i < RegisterImpl::number_of_registers; i++) { Register r = as_Register(i); - if (r < rheapbase && r != rscratch1 && r != rscratch2) { + if (r <= rfp && r != rscratch1 && r != rscratch2) { // SP offsets are in 4-byte words. // Register slots are 8 bytes wide, 32 floating-point registers. int sp_offset = RegisterImpl::max_slots_per_register * i +